lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   79    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   80    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   81    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   82    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   83    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   84    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   85    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  142
  143#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  144pub enum ProgressToken {
  145    Number(i32),
  146    String(SharedString),
  147}
  148
  149impl std::fmt::Display for ProgressToken {
  150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  151        match self {
  152            Self::Number(number) => write!(f, "{number}"),
  153            Self::String(string) => write!(f, "{string}"),
  154        }
  155    }
  156}
  157
  158impl ProgressToken {
  159    fn from_lsp(value: lsp::NumberOrString) -> Self {
  160        match value {
  161            lsp::NumberOrString::Number(number) => Self::Number(number),
  162            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  163        }
  164    }
  165
  166    fn to_lsp(&self) -> lsp::NumberOrString {
  167        match self {
  168            Self::Number(number) => lsp::NumberOrString::Number(*number),
  169            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  170        }
  171    }
  172
  173    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  174        Some(match value.value? {
  175            proto::progress_token::Value::Number(number) => Self::Number(number),
  176            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  177        })
  178    }
  179
  180    fn to_proto(&self) -> proto::ProgressToken {
  181        proto::ProgressToken {
  182            value: Some(match self {
  183                Self::Number(number) => proto::progress_token::Value::Number(*number),
  184                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  185            }),
  186        }
  187    }
  188}
  189
  190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  191pub enum FormatTrigger {
  192    Save,
  193    Manual,
  194}
  195
  196pub enum LspFormatTarget {
  197    Buffers,
  198    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  199}
  200
  201pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  202
  203impl FormatTrigger {
  204    fn from_proto(value: i32) -> FormatTrigger {
  205        match value {
  206            0 => FormatTrigger::Save,
  207            1 => FormatTrigger::Manual,
  208            _ => FormatTrigger::Save,
  209        }
  210    }
  211}
  212
  213#[derive(Clone)]
  214struct UnifiedLanguageServer {
  215    id: LanguageServerId,
  216    project_roots: HashSet<Arc<RelPath>>,
  217}
  218
  219#[derive(Clone, Hash, PartialEq, Eq)]
  220struct LanguageServerSeed {
  221    worktree_id: WorktreeId,
  222    name: LanguageServerName,
  223    toolchain: Option<Toolchain>,
  224    settings: Arc<LspSettings>,
  225}
  226
  227#[derive(Debug)]
  228pub struct DocumentDiagnosticsUpdate<'a, D> {
  229    pub diagnostics: D,
  230    pub result_id: Option<String>,
  231    pub server_id: LanguageServerId,
  232    pub disk_based_sources: Cow<'a, [String]>,
  233}
  234
  235pub struct DocumentDiagnostics {
  236    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  237    document_abs_path: PathBuf,
  238    version: Option<i32>,
  239}
  240
  241#[derive(Default, Debug)]
  242struct DynamicRegistrations {
  243    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  244    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  245}
  246
  247pub struct LocalLspStore {
  248    weak: WeakEntity<LspStore>,
  249    worktree_store: Entity<WorktreeStore>,
  250    toolchain_store: Entity<LocalToolchainStore>,
  251    http_client: Arc<dyn HttpClient>,
  252    environment: Entity<ProjectEnvironment>,
  253    fs: Arc<dyn Fs>,
  254    languages: Arc<LanguageRegistry>,
  255    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  256    yarn: Entity<YarnPathStore>,
  257    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  258    buffers_being_formatted: HashSet<BufferId>,
  259    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  260    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  261    watched_manifest_filenames: HashSet<ManifestName>,
  262    language_server_paths_watched_for_rename:
  263        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  264    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  265    supplementary_language_servers:
  266        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  267    prettier_store: Entity<PrettierStore>,
  268    next_diagnostic_group_id: usize,
  269    diagnostics: HashMap<
  270        WorktreeId,
  271        HashMap<
  272            Arc<RelPath>,
  273            Vec<(
  274                LanguageServerId,
  275                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276            )>,
  277        >,
  278    >,
  279    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  280    _subscription: gpui::Subscription,
  281    lsp_tree: LanguageServerTree,
  282    registered_buffers: HashMap<BufferId, usize>,
  283    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  284    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  285}
  286
  287impl LocalLspStore {
  288    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  289    pub fn running_language_server_for_id(
  290        &self,
  291        id: LanguageServerId,
  292    ) -> Option<&Arc<LanguageServer>> {
  293        let language_server_state = self.language_servers.get(&id)?;
  294
  295        match language_server_state {
  296            LanguageServerState::Running { server, .. } => Some(server),
  297            LanguageServerState::Starting { .. } => None,
  298        }
  299    }
  300
  301    fn get_or_insert_language_server(
  302        &mut self,
  303        worktree_handle: &Entity<Worktree>,
  304        delegate: Arc<LocalLspAdapterDelegate>,
  305        disposition: &Arc<LaunchDisposition>,
  306        language_name: &LanguageName,
  307        cx: &mut App,
  308    ) -> LanguageServerId {
  309        let key = LanguageServerSeed {
  310            worktree_id: worktree_handle.read(cx).id(),
  311            name: disposition.server_name.clone(),
  312            settings: disposition.settings.clone(),
  313            toolchain: disposition.toolchain.clone(),
  314        };
  315        if let Some(state) = self.language_server_ids.get_mut(&key) {
  316            state.project_roots.insert(disposition.path.path.clone());
  317            state.id
  318        } else {
  319            let adapter = self
  320                .languages
  321                .lsp_adapters(language_name)
  322                .into_iter()
  323                .find(|adapter| adapter.name() == disposition.server_name)
  324                .expect("To find LSP adapter");
  325            let new_language_server_id = self.start_language_server(
  326                worktree_handle,
  327                delegate,
  328                adapter,
  329                disposition.settings.clone(),
  330                key.clone(),
  331                cx,
  332            );
  333            if let Some(state) = self.language_server_ids.get_mut(&key) {
  334                state.project_roots.insert(disposition.path.path.clone());
  335            } else {
  336                debug_assert!(
  337                    false,
  338                    "Expected `start_language_server` to ensure that `key` exists in a map"
  339                );
  340            }
  341            new_language_server_id
  342        }
  343    }
  344
  345    fn start_language_server(
  346        &mut self,
  347        worktree_handle: &Entity<Worktree>,
  348        delegate: Arc<LocalLspAdapterDelegate>,
  349        adapter: Arc<CachedLspAdapter>,
  350        settings: Arc<LspSettings>,
  351        key: LanguageServerSeed,
  352        cx: &mut App,
  353    ) -> LanguageServerId {
  354        let worktree = worktree_handle.read(cx);
  355
  356        let root_path = worktree.abs_path();
  357        let toolchain = key.toolchain.clone();
  358        let override_options = settings.initialization_options.clone();
  359
  360        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  361
  362        let server_id = self.languages.next_language_server_id();
  363        log::trace!(
  364            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  365            adapter.name.0
  366        );
  367
  368        let binary = self.get_language_server_binary(
  369            adapter.clone(),
  370            settings,
  371            toolchain.clone(),
  372            delegate.clone(),
  373            true,
  374            cx,
  375        );
  376        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  377
  378        let pending_server = cx.spawn({
  379            let adapter = adapter.clone();
  380            let server_name = adapter.name.clone();
  381            let stderr_capture = stderr_capture.clone();
  382            #[cfg(any(test, feature = "test-support"))]
  383            let lsp_store = self.weak.clone();
  384            let pending_workspace_folders = pending_workspace_folders.clone();
  385            async move |cx| {
  386                let binary = binary.await?;
  387                #[cfg(any(test, feature = "test-support"))]
  388                if let Some(server) = lsp_store
  389                    .update(&mut cx.clone(), |this, cx| {
  390                        this.languages.create_fake_language_server(
  391                            server_id,
  392                            &server_name,
  393                            binary.clone(),
  394                            &mut cx.to_async(),
  395                        )
  396                    })
  397                    .ok()
  398                    .flatten()
  399                {
  400                    return Ok(server);
  401                }
  402
  403                let code_action_kinds = adapter.code_action_kinds();
  404                lsp::LanguageServer::new(
  405                    stderr_capture,
  406                    server_id,
  407                    server_name,
  408                    binary,
  409                    &root_path,
  410                    code_action_kinds,
  411                    Some(pending_workspace_folders),
  412                    cx,
  413                )
  414            }
  415        });
  416
  417        let startup = {
  418            let server_name = adapter.name.0.clone();
  419            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  420            let key = key.clone();
  421            let adapter = adapter.clone();
  422            let lsp_store = self.weak.clone();
  423            let pending_workspace_folders = pending_workspace_folders.clone();
  424
  425            let pull_diagnostics = ProjectSettings::get_global(cx)
  426                .diagnostics
  427                .lsp_pull_diagnostics
  428                .enabled;
  429            cx.spawn(async move |cx| {
  430                let result = async {
  431                    let language_server = pending_server.await?;
  432
  433                    let workspace_config = Self::workspace_configuration_for_adapter(
  434                        adapter.adapter.clone(),
  435                        &delegate,
  436                        toolchain,
  437                        cx,
  438                    )
  439                    .await?;
  440
  441                    let mut initialization_options = Self::initialization_options_for_adapter(
  442                        adapter.adapter.clone(),
  443                        &delegate,
  444                    )
  445                    .await?;
  446
  447                    match (&mut initialization_options, override_options) {
  448                        (Some(initialization_options), Some(override_options)) => {
  449                            merge_json_value_into(override_options, initialization_options);
  450                        }
  451                        (None, override_options) => initialization_options = override_options,
  452                        _ => {}
  453                    }
  454
  455                    let initialization_params = cx.update(|cx| {
  456                        let mut params =
  457                            language_server.default_initialize_params(pull_diagnostics, cx);
  458                        params.initialization_options = initialization_options;
  459                        adapter.adapter.prepare_initialize_params(params, cx)
  460                    })??;
  461
  462                    Self::setup_lsp_messages(
  463                        lsp_store.clone(),
  464                        &language_server,
  465                        delegate.clone(),
  466                        adapter.clone(),
  467                    );
  468
  469                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  470                        settings: workspace_config,
  471                    };
  472                    let language_server = cx
  473                        .update(|cx| {
  474                            language_server.initialize(
  475                                initialization_params,
  476                                Arc::new(did_change_configuration_params.clone()),
  477                                cx,
  478                            )
  479                        })?
  480                        .await
  481                        .inspect_err(|_| {
  482                            if let Some(lsp_store) = lsp_store.upgrade() {
  483                                lsp_store
  484                                    .update(cx, |lsp_store, cx| {
  485                                        lsp_store.cleanup_lsp_data(server_id);
  486                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  487                                    })
  488                                    .ok();
  489                            }
  490                        })?;
  491
  492                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  493                        did_change_configuration_params,
  494                    )?;
  495
  496                    anyhow::Ok(language_server)
  497                }
  498                .await;
  499
  500                match result {
  501                    Ok(server) => {
  502                        lsp_store
  503                            .update(cx, |lsp_store, cx| {
  504                                lsp_store.insert_newly_running_language_server(
  505                                    adapter,
  506                                    server.clone(),
  507                                    server_id,
  508                                    key,
  509                                    pending_workspace_folders,
  510                                    cx,
  511                                );
  512                            })
  513                            .ok();
  514                        stderr_capture.lock().take();
  515                        Some(server)
  516                    }
  517
  518                    Err(err) => {
  519                        let log = stderr_capture.lock().take().unwrap_or_default();
  520                        delegate.update_status(
  521                            adapter.name(),
  522                            BinaryStatus::Failed {
  523                                error: if log.is_empty() {
  524                                    format!("{err:#}")
  525                                } else {
  526                                    format!("{err:#}\n-- stderr --\n{log}")
  527                                },
  528                            },
  529                        );
  530                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  531                        if !log.is_empty() {
  532                            log::error!("server stderr: {log}");
  533                        }
  534                        None
  535                    }
  536                }
  537            })
  538        };
  539        let state = LanguageServerState::Starting {
  540            startup,
  541            pending_workspace_folders,
  542        };
  543
  544        self.languages
  545            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  546
  547        self.language_servers.insert(server_id, state);
  548        self.language_server_ids
  549            .entry(key)
  550            .or_insert(UnifiedLanguageServer {
  551                id: server_id,
  552                project_roots: Default::default(),
  553            });
  554        server_id
  555    }
  556
  557    fn get_language_server_binary(
  558        &self,
  559        adapter: Arc<CachedLspAdapter>,
  560        settings: Arc<LspSettings>,
  561        toolchain: Option<Toolchain>,
  562        delegate: Arc<dyn LspAdapterDelegate>,
  563        allow_binary_download: bool,
  564        cx: &mut App,
  565    ) -> Task<Result<LanguageServerBinary>> {
  566        if let Some(settings) = &settings.binary
  567            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  568        {
  569            let settings = settings.clone();
  570
  571            return cx.background_spawn(async move {
  572                let mut env = delegate.shell_env().await;
  573                env.extend(settings.env.unwrap_or_default());
  574
  575                Ok(LanguageServerBinary {
  576                    path: delegate.resolve_executable_path(path),
  577                    env: Some(env),
  578                    arguments: settings
  579                        .arguments
  580                        .unwrap_or_default()
  581                        .iter()
  582                        .map(Into::into)
  583                        .collect(),
  584                })
  585            });
  586        }
  587        let lsp_binary_options = LanguageServerBinaryOptions {
  588            allow_path_lookup: !settings
  589                .binary
  590                .as_ref()
  591                .and_then(|b| b.ignore_system_version)
  592                .unwrap_or_default(),
  593            allow_binary_download,
  594            pre_release: settings
  595                .fetch
  596                .as_ref()
  597                .and_then(|f| f.pre_release)
  598                .unwrap_or(false),
  599        };
  600
  601        cx.spawn(async move |cx| {
  602            let binary_result = adapter
  603                .clone()
  604                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  605                .await;
  606
  607            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  608
  609            let mut binary = binary_result?;
  610            let mut shell_env = delegate.shell_env().await;
  611
  612            shell_env.extend(binary.env.unwrap_or_default());
  613
  614            if let Some(settings) = settings.binary.as_ref() {
  615                if let Some(arguments) = &settings.arguments {
  616                    binary.arguments = arguments.iter().map(Into::into).collect();
  617                }
  618                if let Some(env) = &settings.env {
  619                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  620                }
  621            }
  622
  623            binary.env = Some(shell_env);
  624            Ok(binary)
  625        })
  626    }
  627
  628    fn setup_lsp_messages(
  629        lsp_store: WeakEntity<LspStore>,
  630        language_server: &LanguageServer,
  631        delegate: Arc<dyn LspAdapterDelegate>,
  632        adapter: Arc<CachedLspAdapter>,
  633    ) {
  634        let name = language_server.name();
  635        let server_id = language_server.server_id();
  636        language_server
  637            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  638                let adapter = adapter.clone();
  639                let this = lsp_store.clone();
  640                move |mut params, cx| {
  641                    let adapter = adapter.clone();
  642                    if let Some(this) = this.upgrade() {
  643                        this.update(cx, |this, cx| {
  644                            {
  645                                let buffer = params
  646                                    .uri
  647                                    .to_file_path()
  648                                    .map(|file_path| this.get_buffer(&file_path, cx))
  649                                    .ok()
  650                                    .flatten();
  651                                adapter.process_diagnostics(&mut params, server_id, buffer);
  652                            }
  653
  654                            this.merge_lsp_diagnostics(
  655                                DiagnosticSourceKind::Pushed,
  656                                vec![DocumentDiagnosticsUpdate {
  657                                    server_id,
  658                                    diagnostics: params,
  659                                    result_id: None,
  660                                    disk_based_sources: Cow::Borrowed(
  661                                        &adapter.disk_based_diagnostic_sources,
  662                                    ),
  663                                }],
  664                                |_, diagnostic, cx| match diagnostic.source_kind {
  665                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  666                                        adapter.retain_old_diagnostic(diagnostic, cx)
  667                                    }
  668                                    DiagnosticSourceKind::Pulled => true,
  669                                },
  670                                cx,
  671                            )
  672                            .log_err();
  673                        })
  674                        .ok();
  675                    }
  676                }
  677            })
  678            .detach();
  679        language_server
  680            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  681                let adapter = adapter.adapter.clone();
  682                let delegate = delegate.clone();
  683                let this = lsp_store.clone();
  684                move |params, cx| {
  685                    let adapter = adapter.clone();
  686                    let delegate = delegate.clone();
  687                    let this = this.clone();
  688                    let mut cx = cx.clone();
  689                    async move {
  690                        let toolchain_for_id = this
  691                            .update(&mut cx, |this, _| {
  692                                this.as_local()?.language_server_ids.iter().find_map(
  693                                    |(seed, value)| {
  694                                        (value.id == server_id).then(|| seed.toolchain.clone())
  695                                    },
  696                                )
  697                            })?
  698                            .context("Expected the LSP store to be in a local mode")?;
  699                        let workspace_config = Self::workspace_configuration_for_adapter(
  700                            adapter.clone(),
  701                            &delegate,
  702                            toolchain_for_id,
  703                            &mut cx,
  704                        )
  705                        .await?;
  706
  707                        Ok(params
  708                            .items
  709                            .into_iter()
  710                            .map(|item| {
  711                                if let Some(section) = &item.section {
  712                                    workspace_config
  713                                        .get(section)
  714                                        .cloned()
  715                                        .unwrap_or(serde_json::Value::Null)
  716                                } else {
  717                                    workspace_config.clone()
  718                                }
  719                            })
  720                            .collect())
  721                    }
  722                }
  723            })
  724            .detach();
  725
  726        language_server
  727            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  728                let this = lsp_store.clone();
  729                move |_, cx| {
  730                    let this = this.clone();
  731                    let cx = cx.clone();
  732                    async move {
  733                        let Some(server) =
  734                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  735                        else {
  736                            return Ok(None);
  737                        };
  738                        let root = server.workspace_folders();
  739                        Ok(Some(
  740                            root.into_iter()
  741                                .map(|uri| WorkspaceFolder {
  742                                    uri,
  743                                    name: Default::default(),
  744                                })
  745                                .collect(),
  746                        ))
  747                    }
  748                }
  749            })
  750            .detach();
  751        // Even though we don't have handling for these requests, respond to them to
  752        // avoid stalling any language server like `gopls` which waits for a response
  753        // to these requests when initializing.
  754        language_server
  755            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  756                let this = lsp_store.clone();
  757                move |params, cx| {
  758                    let this = this.clone();
  759                    let mut cx = cx.clone();
  760                    async move {
  761                        this.update(&mut cx, |this, _| {
  762                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  763                            {
  764                                status
  765                                    .progress_tokens
  766                                    .insert(ProgressToken::from_lsp(params.token));
  767                            }
  768                        })?;
  769
  770                        Ok(())
  771                    }
  772                }
  773            })
  774            .detach();
  775
  776        language_server
  777            .on_request::<lsp::request::RegisterCapability, _, _>({
  778                let lsp_store = lsp_store.clone();
  779                move |params, cx| {
  780                    let lsp_store = lsp_store.clone();
  781                    let mut cx = cx.clone();
  782                    async move {
  783                        lsp_store
  784                            .update(&mut cx, |lsp_store, cx| {
  785                                if lsp_store.as_local().is_some() {
  786                                    match lsp_store
  787                                        .register_server_capabilities(server_id, params, cx)
  788                                    {
  789                                        Ok(()) => {}
  790                                        Err(e) => {
  791                                            log::error!(
  792                                                "Failed to register server capabilities: {e:#}"
  793                                            );
  794                                        }
  795                                    };
  796                                }
  797                            })
  798                            .ok();
  799                        Ok(())
  800                    }
  801                }
  802            })
  803            .detach();
  804
  805        language_server
  806            .on_request::<lsp::request::UnregisterCapability, _, _>({
  807                let lsp_store = lsp_store.clone();
  808                move |params, cx| {
  809                    let lsp_store = lsp_store.clone();
  810                    let mut cx = cx.clone();
  811                    async move {
  812                        lsp_store
  813                            .update(&mut cx, |lsp_store, cx| {
  814                                if lsp_store.as_local().is_some() {
  815                                    match lsp_store
  816                                        .unregister_server_capabilities(server_id, params, cx)
  817                                    {
  818                                        Ok(()) => {}
  819                                        Err(e) => {
  820                                            log::error!(
  821                                                "Failed to unregister server capabilities: {e:#}"
  822                                            );
  823                                        }
  824                                    }
  825                                }
  826                            })
  827                            .ok();
  828                        Ok(())
  829                    }
  830                }
  831            })
  832            .detach();
  833
  834        language_server
  835            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  836                let this = lsp_store.clone();
  837                move |params, cx| {
  838                    let mut cx = cx.clone();
  839                    let this = this.clone();
  840                    async move {
  841                        LocalLspStore::on_lsp_workspace_edit(
  842                            this.clone(),
  843                            params,
  844                            server_id,
  845                            &mut cx,
  846                        )
  847                        .await
  848                    }
  849                }
  850            })
  851            .detach();
  852
  853        language_server
  854            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  855                let lsp_store = lsp_store.clone();
  856                let request_id = Arc::new(AtomicUsize::new(0));
  857                move |(), cx| {
  858                    let lsp_store = lsp_store.clone();
  859                    let request_id = request_id.clone();
  860                    let mut cx = cx.clone();
  861                    async move {
  862                        lsp_store
  863                            .update(&mut cx, |lsp_store, cx| {
  864                                let request_id =
  865                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  866                                cx.emit(LspStoreEvent::RefreshInlayHints {
  867                                    server_id,
  868                                    request_id,
  869                                });
  870                                lsp_store
  871                                    .downstream_client
  872                                    .as_ref()
  873                                    .map(|(client, project_id)| {
  874                                        client.send(proto::RefreshInlayHints {
  875                                            project_id: *project_id,
  876                                            server_id: server_id.to_proto(),
  877                                            request_id: request_id.map(|id| id as u64),
  878                                        })
  879                                    })
  880                            })?
  881                            .transpose()?;
  882                        Ok(())
  883                    }
  884                }
  885            })
  886            .detach();
  887
  888        language_server
  889            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  890                let this = lsp_store.clone();
  891                move |(), cx| {
  892                    let this = this.clone();
  893                    let mut cx = cx.clone();
  894                    async move {
  895                        this.update(&mut cx, |this, cx| {
  896                            cx.emit(LspStoreEvent::RefreshCodeLens);
  897                            this.downstream_client.as_ref().map(|(client, project_id)| {
  898                                client.send(proto::RefreshCodeLens {
  899                                    project_id: *project_id,
  900                                })
  901                            })
  902                        })?
  903                        .transpose()?;
  904                        Ok(())
  905                    }
  906                }
  907            })
  908            .detach();
  909
  910        language_server
  911            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  912                let this = lsp_store.clone();
  913                move |(), cx| {
  914                    let this = this.clone();
  915                    let mut cx = cx.clone();
  916                    async move {
  917                        this.update(&mut cx, |lsp_store, _| {
  918                            lsp_store.pull_workspace_diagnostics(server_id);
  919                            lsp_store
  920                                .downstream_client
  921                                .as_ref()
  922                                .map(|(client, project_id)| {
  923                                    client.send(proto::PullWorkspaceDiagnostics {
  924                                        project_id: *project_id,
  925                                        server_id: server_id.to_proto(),
  926                                    })
  927                                })
  928                        })?
  929                        .transpose()?;
  930                        Ok(())
  931                    }
  932                }
  933            })
  934            .detach();
  935
  936        language_server
  937            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  938                let this = lsp_store.clone();
  939                let name = name.to_string();
  940                move |params, cx| {
  941                    let this = this.clone();
  942                    let name = name.to_string();
  943                    let mut cx = cx.clone();
  944                    async move {
  945                        let actions = params.actions.unwrap_or_default();
  946                        let (tx, rx) = smol::channel::bounded(1);
  947                        let request = LanguageServerPromptRequest {
  948                            level: match params.typ {
  949                                lsp::MessageType::ERROR => PromptLevel::Critical,
  950                                lsp::MessageType::WARNING => PromptLevel::Warning,
  951                                _ => PromptLevel::Info,
  952                            },
  953                            message: params.message,
  954                            actions,
  955                            response_channel: tx,
  956                            lsp_name: name.clone(),
  957                        };
  958
  959                        let did_update = this
  960                            .update(&mut cx, |_, cx| {
  961                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  962                            })
  963                            .is_ok();
  964                        if did_update {
  965                            let response = rx.recv().await.ok();
  966                            Ok(response)
  967                        } else {
  968                            Ok(None)
  969                        }
  970                    }
  971                }
  972            })
  973            .detach();
  974        language_server
  975            .on_notification::<lsp::notification::ShowMessage, _>({
  976                let this = lsp_store.clone();
  977                let name = name.to_string();
  978                move |params, cx| {
  979                    let this = this.clone();
  980                    let name = name.to_string();
  981                    let mut cx = cx.clone();
  982
  983                    let (tx, _) = smol::channel::bounded(1);
  984                    let request = LanguageServerPromptRequest {
  985                        level: match params.typ {
  986                            lsp::MessageType::ERROR => PromptLevel::Critical,
  987                            lsp::MessageType::WARNING => PromptLevel::Warning,
  988                            _ => PromptLevel::Info,
  989                        },
  990                        message: params.message,
  991                        actions: vec![],
  992                        response_channel: tx,
  993                        lsp_name: name,
  994                    };
  995
  996                    let _ = this.update(&mut cx, |_, cx| {
  997                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  998                    });
  999                }
 1000            })
 1001            .detach();
 1002
 1003        let disk_based_diagnostics_progress_token =
 1004            adapter.disk_based_diagnostics_progress_token.clone();
 1005
 1006        language_server
 1007            .on_notification::<lsp::notification::Progress, _>({
 1008                let this = lsp_store.clone();
 1009                move |params, cx| {
 1010                    if let Some(this) = this.upgrade() {
 1011                        this.update(cx, |this, cx| {
 1012                            this.on_lsp_progress(
 1013                                params,
 1014                                server_id,
 1015                                disk_based_diagnostics_progress_token.clone(),
 1016                                cx,
 1017                            );
 1018                        })
 1019                        .ok();
 1020                    }
 1021                }
 1022            })
 1023            .detach();
 1024
 1025        language_server
 1026            .on_notification::<lsp::notification::LogMessage, _>({
 1027                let this = lsp_store.clone();
 1028                move |params, cx| {
 1029                    if let Some(this) = this.upgrade() {
 1030                        this.update(cx, |_, cx| {
 1031                            cx.emit(LspStoreEvent::LanguageServerLog(
 1032                                server_id,
 1033                                LanguageServerLogType::Log(params.typ),
 1034                                params.message,
 1035                            ));
 1036                        })
 1037                        .ok();
 1038                    }
 1039                }
 1040            })
 1041            .detach();
 1042
 1043        language_server
 1044            .on_notification::<lsp::notification::LogTrace, _>({
 1045                let this = lsp_store.clone();
 1046                move |params, cx| {
 1047                    let mut cx = cx.clone();
 1048                    if let Some(this) = this.upgrade() {
 1049                        this.update(&mut cx, |_, cx| {
 1050                            cx.emit(LspStoreEvent::LanguageServerLog(
 1051                                server_id,
 1052                                LanguageServerLogType::Trace {
 1053                                    verbose_info: params.verbose,
 1054                                },
 1055                                params.message,
 1056                            ));
 1057                        })
 1058                        .ok();
 1059                    }
 1060                }
 1061            })
 1062            .detach();
 1063
 1064        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1065        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1066        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1067        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1068    }
 1069
 1070    fn shutdown_language_servers_on_quit(
 1071        &mut self,
 1072        _: &mut Context<LspStore>,
 1073    ) -> impl Future<Output = ()> + use<> {
 1074        let shutdown_futures = self
 1075            .language_servers
 1076            .drain()
 1077            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1078            .collect::<Vec<_>>();
 1079
 1080        async move {
 1081            join_all(shutdown_futures).await;
 1082        }
 1083    }
 1084
 1085    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1086        match server_state {
 1087            LanguageServerState::Running { server, .. } => {
 1088                if let Some(shutdown) = server.shutdown() {
 1089                    shutdown.await;
 1090                }
 1091            }
 1092            LanguageServerState::Starting { startup, .. } => {
 1093                if let Some(server) = startup.await
 1094                    && let Some(shutdown) = server.shutdown()
 1095                {
 1096                    shutdown.await;
 1097                }
 1098            }
 1099        }
 1100        Ok(())
 1101    }
 1102
 1103    fn language_servers_for_worktree(
 1104        &self,
 1105        worktree_id: WorktreeId,
 1106    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1107        self.language_server_ids
 1108            .iter()
 1109            .filter_map(move |(seed, state)| {
 1110                if seed.worktree_id != worktree_id {
 1111                    return None;
 1112                }
 1113
 1114                if let Some(LanguageServerState::Running { server, .. }) =
 1115                    self.language_servers.get(&state.id)
 1116                {
 1117                    Some(server)
 1118                } else {
 1119                    None
 1120                }
 1121            })
 1122    }
 1123
 1124    fn language_server_ids_for_project_path(
 1125        &self,
 1126        project_path: ProjectPath,
 1127        language: &Language,
 1128        cx: &mut App,
 1129    ) -> Vec<LanguageServerId> {
 1130        let Some(worktree) = self
 1131            .worktree_store
 1132            .read(cx)
 1133            .worktree_for_id(project_path.worktree_id, cx)
 1134        else {
 1135            return Vec::new();
 1136        };
 1137        let delegate: Arc<dyn ManifestDelegate> =
 1138            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1139
 1140        self.lsp_tree
 1141            .get(
 1142                project_path,
 1143                language.name(),
 1144                language.manifest(),
 1145                &delegate,
 1146                cx,
 1147            )
 1148            .collect::<Vec<_>>()
 1149    }
 1150
 1151    fn language_server_ids_for_buffer(
 1152        &self,
 1153        buffer: &Buffer,
 1154        cx: &mut App,
 1155    ) -> Vec<LanguageServerId> {
 1156        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1157            let worktree_id = file.worktree_id(cx);
 1158
 1159            let path: Arc<RelPath> = file
 1160                .path()
 1161                .parent()
 1162                .map(Arc::from)
 1163                .unwrap_or_else(|| file.path().clone());
 1164            let worktree_path = ProjectPath { worktree_id, path };
 1165            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1166        } else {
 1167            Vec::new()
 1168        }
 1169    }
 1170
 1171    fn language_servers_for_buffer<'a>(
 1172        &'a self,
 1173        buffer: &'a Buffer,
 1174        cx: &'a mut App,
 1175    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1176        self.language_server_ids_for_buffer(buffer, cx)
 1177            .into_iter()
 1178            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1179                LanguageServerState::Running {
 1180                    adapter, server, ..
 1181                } => Some((adapter, server)),
 1182                _ => None,
 1183            })
 1184    }
 1185
 1186    async fn execute_code_action_kind_locally(
 1187        lsp_store: WeakEntity<LspStore>,
 1188        mut buffers: Vec<Entity<Buffer>>,
 1189        kind: CodeActionKind,
 1190        push_to_history: bool,
 1191        cx: &mut AsyncApp,
 1192    ) -> anyhow::Result<ProjectTransaction> {
 1193        // Do not allow multiple concurrent code actions requests for the
 1194        // same buffer.
 1195        lsp_store.update(cx, |this, cx| {
 1196            let this = this.as_local_mut().unwrap();
 1197            buffers.retain(|buffer| {
 1198                this.buffers_being_formatted
 1199                    .insert(buffer.read(cx).remote_id())
 1200            });
 1201        })?;
 1202        let _cleanup = defer({
 1203            let this = lsp_store.clone();
 1204            let mut cx = cx.clone();
 1205            let buffers = &buffers;
 1206            move || {
 1207                this.update(&mut cx, |this, cx| {
 1208                    let this = this.as_local_mut().unwrap();
 1209                    for buffer in buffers {
 1210                        this.buffers_being_formatted
 1211                            .remove(&buffer.read(cx).remote_id());
 1212                    }
 1213                })
 1214                .ok();
 1215            }
 1216        });
 1217        let mut project_transaction = ProjectTransaction::default();
 1218
 1219        for buffer in &buffers {
 1220            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1221                buffer.update(cx, |buffer, cx| {
 1222                    lsp_store
 1223                        .as_local()
 1224                        .unwrap()
 1225                        .language_servers_for_buffer(buffer, cx)
 1226                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1227                        .collect::<Vec<_>>()
 1228                })
 1229            })?;
 1230            for (_, language_server) in adapters_and_servers.iter() {
 1231                let actions = Self::get_server_code_actions_from_action_kinds(
 1232                    &lsp_store,
 1233                    language_server.server_id(),
 1234                    vec![kind.clone()],
 1235                    buffer,
 1236                    cx,
 1237                )
 1238                .await?;
 1239                Self::execute_code_actions_on_server(
 1240                    &lsp_store,
 1241                    language_server,
 1242                    actions,
 1243                    push_to_history,
 1244                    &mut project_transaction,
 1245                    cx,
 1246                )
 1247                .await?;
 1248            }
 1249        }
 1250        Ok(project_transaction)
 1251    }
 1252
 1253    async fn format_locally(
 1254        lsp_store: WeakEntity<LspStore>,
 1255        mut buffers: Vec<FormattableBuffer>,
 1256        push_to_history: bool,
 1257        trigger: FormatTrigger,
 1258        logger: zlog::Logger,
 1259        cx: &mut AsyncApp,
 1260    ) -> anyhow::Result<ProjectTransaction> {
 1261        // Do not allow multiple concurrent formatting requests for the
 1262        // same buffer.
 1263        lsp_store.update(cx, |this, cx| {
 1264            let this = this.as_local_mut().unwrap();
 1265            buffers.retain(|buffer| {
 1266                this.buffers_being_formatted
 1267                    .insert(buffer.handle.read(cx).remote_id())
 1268            });
 1269        })?;
 1270
 1271        let _cleanup = defer({
 1272            let this = lsp_store.clone();
 1273            let mut cx = cx.clone();
 1274            let buffers = &buffers;
 1275            move || {
 1276                this.update(&mut cx, |this, cx| {
 1277                    let this = this.as_local_mut().unwrap();
 1278                    for buffer in buffers {
 1279                        this.buffers_being_formatted
 1280                            .remove(&buffer.handle.read(cx).remote_id());
 1281                    }
 1282                })
 1283                .ok();
 1284            }
 1285        });
 1286
 1287        let mut project_transaction = ProjectTransaction::default();
 1288
 1289        for buffer in &buffers {
 1290            zlog::debug!(
 1291                logger =>
 1292                "formatting buffer '{:?}'",
 1293                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1294            );
 1295            // Create an empty transaction to hold all of the formatting edits.
 1296            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1297                // ensure no transactions created while formatting are
 1298                // grouped with the previous transaction in the history
 1299                // based on the transaction group interval
 1300                buffer.finalize_last_transaction();
 1301                buffer
 1302                    .start_transaction()
 1303                    .context("transaction already open")?;
 1304                buffer.end_transaction(cx);
 1305                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1306                buffer.finalize_last_transaction();
 1307                anyhow::Ok(transaction_id)
 1308            })??;
 1309
 1310            let result = Self::format_buffer_locally(
 1311                lsp_store.clone(),
 1312                buffer,
 1313                formatting_transaction_id,
 1314                trigger,
 1315                logger,
 1316                cx,
 1317            )
 1318            .await;
 1319
 1320            buffer.handle.update(cx, |buffer, cx| {
 1321                let Some(formatting_transaction) =
 1322                    buffer.get_transaction(formatting_transaction_id).cloned()
 1323                else {
 1324                    zlog::warn!(logger => "no formatting transaction");
 1325                    return;
 1326                };
 1327                if formatting_transaction.edit_ids.is_empty() {
 1328                    zlog::debug!(logger => "no changes made while formatting");
 1329                    buffer.forget_transaction(formatting_transaction_id);
 1330                    return;
 1331                }
 1332                if !push_to_history {
 1333                    zlog::trace!(logger => "forgetting format transaction");
 1334                    buffer.forget_transaction(formatting_transaction.id);
 1335                }
 1336                project_transaction
 1337                    .0
 1338                    .insert(cx.entity(), formatting_transaction);
 1339            })?;
 1340
 1341            result?;
 1342        }
 1343
 1344        Ok(project_transaction)
 1345    }
 1346
 1347    async fn format_buffer_locally(
 1348        lsp_store: WeakEntity<LspStore>,
 1349        buffer: &FormattableBuffer,
 1350        formatting_transaction_id: clock::Lamport,
 1351        trigger: FormatTrigger,
 1352        logger: zlog::Logger,
 1353        cx: &mut AsyncApp,
 1354    ) -> Result<()> {
 1355        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1356            buffer.handle.update(cx, |buffer, cx| {
 1357                let adapters_and_servers = lsp_store
 1358                    .as_local()
 1359                    .unwrap()
 1360                    .language_servers_for_buffer(buffer, cx)
 1361                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1362                    .collect::<Vec<_>>();
 1363                let settings =
 1364                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1365                        .into_owned();
 1366                (adapters_and_servers, settings)
 1367            })
 1368        })?;
 1369
 1370        /// Apply edits to the buffer that will become part of the formatting transaction.
 1371        /// Fails if the buffer has been edited since the start of that transaction.
 1372        fn extend_formatting_transaction(
 1373            buffer: &FormattableBuffer,
 1374            formatting_transaction_id: text::TransactionId,
 1375            cx: &mut AsyncApp,
 1376            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1377        ) -> anyhow::Result<()> {
 1378            buffer.handle.update(cx, |buffer, cx| {
 1379                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1380                if last_transaction_id != Some(formatting_transaction_id) {
 1381                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1382                }
 1383                buffer.start_transaction();
 1384                operation(buffer, cx);
 1385                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1386                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1387                }
 1388                Ok(())
 1389            })?
 1390        }
 1391
 1392        // handle whitespace formatting
 1393        if settings.remove_trailing_whitespace_on_save {
 1394            zlog::trace!(logger => "removing trailing whitespace");
 1395            let diff = buffer
 1396                .handle
 1397                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1398                .await;
 1399            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1400                buffer.apply_diff(diff, cx);
 1401            })?;
 1402        }
 1403
 1404        if settings.ensure_final_newline_on_save {
 1405            zlog::trace!(logger => "ensuring final newline");
 1406            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1407                buffer.ensure_final_newline(cx);
 1408            })?;
 1409        }
 1410
 1411        // Formatter for `code_actions_on_format` that runs before
 1412        // the rest of the formatters
 1413        let mut code_actions_on_format_formatters = None;
 1414        let should_run_code_actions_on_format = !matches!(
 1415            (trigger, &settings.format_on_save),
 1416            (FormatTrigger::Save, &FormatOnSave::Off)
 1417        );
 1418        if should_run_code_actions_on_format {
 1419            let have_code_actions_to_run_on_format = settings
 1420                .code_actions_on_format
 1421                .values()
 1422                .any(|enabled| *enabled);
 1423            if have_code_actions_to_run_on_format {
 1424                zlog::trace!(logger => "going to run code actions on format");
 1425                code_actions_on_format_formatters = Some(
 1426                    settings
 1427                        .code_actions_on_format
 1428                        .iter()
 1429                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1430                        .cloned()
 1431                        .map(Formatter::CodeAction)
 1432                        .collect::<Vec<_>>(),
 1433                );
 1434            }
 1435        }
 1436
 1437        let formatters = match (trigger, &settings.format_on_save) {
 1438            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1439            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1440                settings.formatter.as_ref()
 1441            }
 1442        };
 1443
 1444        let formatters = code_actions_on_format_formatters
 1445            .iter()
 1446            .flatten()
 1447            .chain(formatters);
 1448
 1449        for formatter in formatters {
 1450            let formatter = if formatter == &Formatter::Auto {
 1451                if settings.prettier.allowed {
 1452                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1453                    &Formatter::Prettier
 1454                } else {
 1455                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1456                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1457                }
 1458            } else {
 1459                formatter
 1460            };
 1461            match formatter {
 1462                Formatter::Auto => unreachable!("Auto resolved above"),
 1463                Formatter::Prettier => {
 1464                    let logger = zlog::scoped!(logger => "prettier");
 1465                    zlog::trace!(logger => "formatting");
 1466                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1467
 1468                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1469                        lsp_store.prettier_store().unwrap().downgrade()
 1470                    })?;
 1471                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1472                        .await
 1473                        .transpose()?;
 1474                    let Some(diff) = diff else {
 1475                        zlog::trace!(logger => "No changes");
 1476                        continue;
 1477                    };
 1478
 1479                    extend_formatting_transaction(
 1480                        buffer,
 1481                        formatting_transaction_id,
 1482                        cx,
 1483                        |buffer, cx| {
 1484                            buffer.apply_diff(diff, cx);
 1485                        },
 1486                    )?;
 1487                }
 1488                Formatter::External { command, arguments } => {
 1489                    let logger = zlog::scoped!(logger => "command");
 1490                    zlog::trace!(logger => "formatting");
 1491                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1492
 1493                    let diff = Self::format_via_external_command(
 1494                        buffer,
 1495                        command.as_ref(),
 1496                        arguments.as_deref(),
 1497                        cx,
 1498                    )
 1499                    .await
 1500                    .with_context(|| {
 1501                        format!("Failed to format buffer via external command: {}", command)
 1502                    })?;
 1503                    let Some(diff) = diff else {
 1504                        zlog::trace!(logger => "No changes");
 1505                        continue;
 1506                    };
 1507
 1508                    extend_formatting_transaction(
 1509                        buffer,
 1510                        formatting_transaction_id,
 1511                        cx,
 1512                        |buffer, cx| {
 1513                            buffer.apply_diff(diff, cx);
 1514                        },
 1515                    )?;
 1516                }
 1517                Formatter::LanguageServer(specifier) => {
 1518                    let logger = zlog::scoped!(logger => "language-server");
 1519                    zlog::trace!(logger => "formatting");
 1520                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1521
 1522                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1523                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1524                        continue;
 1525                    };
 1526
 1527                    let language_server = match specifier {
 1528                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1529                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1530                                if adapter.name.0.as_ref() == name {
 1531                                    Some(server.clone())
 1532                                } else {
 1533                                    None
 1534                                }
 1535                            })
 1536                        }
 1537                        settings::LanguageServerFormatterSpecifier::Current => {
 1538                            adapters_and_servers.first().map(|e| e.1.clone())
 1539                        }
 1540                    };
 1541
 1542                    let Some(language_server) = language_server else {
 1543                        log::debug!(
 1544                            "No language server found to format buffer '{:?}'. Skipping",
 1545                            buffer_path_abs.as_path().to_string_lossy()
 1546                        );
 1547                        continue;
 1548                    };
 1549
 1550                    zlog::trace!(
 1551                        logger =>
 1552                        "Formatting buffer '{:?}' using language server '{:?}'",
 1553                        buffer_path_abs.as_path().to_string_lossy(),
 1554                        language_server.name()
 1555                    );
 1556
 1557                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1558                        zlog::trace!(logger => "formatting ranges");
 1559                        Self::format_ranges_via_lsp(
 1560                            &lsp_store,
 1561                            &buffer.handle,
 1562                            ranges,
 1563                            buffer_path_abs,
 1564                            &language_server,
 1565                            &settings,
 1566                            cx,
 1567                        )
 1568                        .await
 1569                        .context("Failed to format ranges via language server")?
 1570                    } else {
 1571                        zlog::trace!(logger => "formatting full");
 1572                        Self::format_via_lsp(
 1573                            &lsp_store,
 1574                            &buffer.handle,
 1575                            buffer_path_abs,
 1576                            &language_server,
 1577                            &settings,
 1578                            cx,
 1579                        )
 1580                        .await
 1581                        .context("failed to format via language server")?
 1582                    };
 1583
 1584                    if edits.is_empty() {
 1585                        zlog::trace!(logger => "No changes");
 1586                        continue;
 1587                    }
 1588                    extend_formatting_transaction(
 1589                        buffer,
 1590                        formatting_transaction_id,
 1591                        cx,
 1592                        |buffer, cx| {
 1593                            buffer.edit(edits, None, cx);
 1594                        },
 1595                    )?;
 1596                }
 1597                Formatter::CodeAction(code_action_name) => {
 1598                    let logger = zlog::scoped!(logger => "code-actions");
 1599                    zlog::trace!(logger => "formatting");
 1600                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1601
 1602                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1603                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1604                        continue;
 1605                    };
 1606
 1607                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1608                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1609
 1610                    let mut actions_and_servers = Vec::new();
 1611
 1612                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1613                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1614                            &lsp_store,
 1615                            language_server.server_id(),
 1616                            vec![code_action_kind.clone()],
 1617                            &buffer.handle,
 1618                            cx,
 1619                        )
 1620                        .await
 1621                        .with_context(|| {
 1622                            format!(
 1623                                "Failed to resolve code action {:?} with language server {}",
 1624                                code_action_kind,
 1625                                language_server.name()
 1626                            )
 1627                        });
 1628                        let Ok(actions) = actions_result else {
 1629                            // note: it may be better to set result to the error and break formatters here
 1630                            // but for now we try to execute the actions that we can resolve and skip the rest
 1631                            zlog::error!(
 1632                                logger =>
 1633                                "Failed to resolve code action {:?} with language server {}",
 1634                                code_action_kind,
 1635                                language_server.name()
 1636                            );
 1637                            continue;
 1638                        };
 1639                        for action in actions {
 1640                            actions_and_servers.push((action, index));
 1641                        }
 1642                    }
 1643
 1644                    if actions_and_servers.is_empty() {
 1645                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1646                        continue;
 1647                    }
 1648
 1649                    'actions: for (mut action, server_index) in actions_and_servers {
 1650                        let server = &adapters_and_servers[server_index].1;
 1651
 1652                        let describe_code_action = |action: &CodeAction| {
 1653                            format!(
 1654                                "code action '{}' with title \"{}\" on server {}",
 1655                                action
 1656                                    .lsp_action
 1657                                    .action_kind()
 1658                                    .unwrap_or("unknown".into())
 1659                                    .as_str(),
 1660                                action.lsp_action.title(),
 1661                                server.name(),
 1662                            )
 1663                        };
 1664
 1665                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1666
 1667                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1668                            zlog::error!(
 1669                                logger =>
 1670                                "Failed to resolve {}. Error: {}",
 1671                                describe_code_action(&action),
 1672                                err
 1673                            );
 1674                            continue;
 1675                        }
 1676
 1677                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1678                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1679                            // but filters out and logs warnings for code actions that require unreasonably
 1680                            // difficult handling on our part, such as:
 1681                            // - applying edits that call commands
 1682                            //   which can result in arbitrary workspace edits being sent from the server that
 1683                            //   have no way of being tied back to the command that initiated them (i.e. we
 1684                            //   can't know which edits are part of the format request, or if the server is done sending
 1685                            //   actions in response to the command)
 1686                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1687                            //   as we then would need to handle such changes correctly in the local history as well
 1688                            //   as the remote history through the ProjectTransaction
 1689                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1690                            // Supporting these actions is not impossible, but not supported as of yet.
 1691                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1692                                zlog::trace!(
 1693                                    logger =>
 1694                                    "No changes for code action. Skipping {}",
 1695                                    describe_code_action(&action),
 1696                                );
 1697                                continue;
 1698                            }
 1699
 1700                            let mut operations = Vec::new();
 1701                            if let Some(document_changes) = edit.document_changes {
 1702                                match document_changes {
 1703                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1704                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1705                                    ),
 1706                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1707                                }
 1708                            } else if let Some(changes) = edit.changes {
 1709                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1710                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1711                                        text_document:
 1712                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1713                                                uri,
 1714                                                version: None,
 1715                                            },
 1716                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1717                                    })
 1718                                }));
 1719                            }
 1720
 1721                            let mut edits = Vec::with_capacity(operations.len());
 1722
 1723                            if operations.is_empty() {
 1724                                zlog::trace!(
 1725                                    logger =>
 1726                                    "No changes for code action. Skipping {}",
 1727                                    describe_code_action(&action),
 1728                                );
 1729                                continue;
 1730                            }
 1731                            for operation in operations {
 1732                                let op = match operation {
 1733                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1734                                    lsp::DocumentChangeOperation::Op(_) => {
 1735                                        zlog::warn!(
 1736                                            logger =>
 1737                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1738                                            describe_code_action(&action),
 1739                                        );
 1740                                        continue 'actions;
 1741                                    }
 1742                                };
 1743                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1744                                    zlog::warn!(
 1745                                        logger =>
 1746                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1747                                        &op.text_document.uri,
 1748                                        describe_code_action(&action),
 1749                                    );
 1750                                    continue 'actions;
 1751                                };
 1752                                if &file_path != buffer_path_abs {
 1753                                    zlog::warn!(
 1754                                        logger =>
 1755                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1756                                        file_path,
 1757                                        buffer_path_abs,
 1758                                        describe_code_action(&action),
 1759                                    );
 1760                                    continue 'actions;
 1761                                }
 1762
 1763                                let mut lsp_edits = Vec::new();
 1764                                for edit in op.edits {
 1765                                    match edit {
 1766                                        Edit::Plain(edit) => {
 1767                                            if !lsp_edits.contains(&edit) {
 1768                                                lsp_edits.push(edit);
 1769                                            }
 1770                                        }
 1771                                        Edit::Annotated(edit) => {
 1772                                            if !lsp_edits.contains(&edit.text_edit) {
 1773                                                lsp_edits.push(edit.text_edit);
 1774                                            }
 1775                                        }
 1776                                        Edit::Snippet(_) => {
 1777                                            zlog::warn!(
 1778                                                logger =>
 1779                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1780                                                describe_code_action(&action),
 1781                                            );
 1782                                            continue 'actions;
 1783                                        }
 1784                                    }
 1785                                }
 1786                                let edits_result = lsp_store
 1787                                    .update(cx, |lsp_store, cx| {
 1788                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1789                                            &buffer.handle,
 1790                                            lsp_edits,
 1791                                            server.server_id(),
 1792                                            op.text_document.version,
 1793                                            cx,
 1794                                        )
 1795                                    })?
 1796                                    .await;
 1797                                let Ok(resolved_edits) = edits_result else {
 1798                                    zlog::warn!(
 1799                                        logger =>
 1800                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1801                                        buffer_path_abs.as_path(),
 1802                                        describe_code_action(&action),
 1803                                    );
 1804                                    continue 'actions;
 1805                                };
 1806                                edits.extend(resolved_edits);
 1807                            }
 1808
 1809                            if edits.is_empty() {
 1810                                zlog::warn!(logger => "No edits resolved from LSP");
 1811                                continue;
 1812                            }
 1813
 1814                            extend_formatting_transaction(
 1815                                buffer,
 1816                                formatting_transaction_id,
 1817                                cx,
 1818                                |buffer, cx| {
 1819                                    zlog::info!(
 1820                                        "Applying edits {edits:?}. Content: {:?}",
 1821                                        buffer.text()
 1822                                    );
 1823                                    buffer.edit(edits, None, cx);
 1824                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1825                                },
 1826                            )?;
 1827                        }
 1828
 1829                        if let Some(command) = action.lsp_action.command() {
 1830                            zlog::warn!(
 1831                                logger =>
 1832                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1833                                &command.command,
 1834                            );
 1835
 1836                            // bail early if command is invalid
 1837                            let server_capabilities = server.capabilities();
 1838                            let available_commands = server_capabilities
 1839                                .execute_command_provider
 1840                                .as_ref()
 1841                                .map(|options| options.commands.as_slice())
 1842                                .unwrap_or_default();
 1843                            if !available_commands.contains(&command.command) {
 1844                                zlog::warn!(
 1845                                    logger =>
 1846                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1847                                    command.command,
 1848                                    server.name(),
 1849                                );
 1850                                continue;
 1851                            }
 1852
 1853                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1854                            extend_formatting_transaction(
 1855                                buffer,
 1856                                formatting_transaction_id,
 1857                                cx,
 1858                                |_, _| {},
 1859                            )?;
 1860                            zlog::info!(logger => "Executing command {}", &command.command);
 1861
 1862                            lsp_store.update(cx, |this, _| {
 1863                                this.as_local_mut()
 1864                                    .unwrap()
 1865                                    .last_workspace_edits_by_language_server
 1866                                    .remove(&server.server_id());
 1867                            })?;
 1868
 1869                            let execute_command_result = server
 1870                                .request::<lsp::request::ExecuteCommand>(
 1871                                    lsp::ExecuteCommandParams {
 1872                                        command: command.command.clone(),
 1873                                        arguments: command.arguments.clone().unwrap_or_default(),
 1874                                        ..Default::default()
 1875                                    },
 1876                                )
 1877                                .await
 1878                                .into_response();
 1879
 1880                            if execute_command_result.is_err() {
 1881                                zlog::error!(
 1882                                    logger =>
 1883                                    "Failed to execute command '{}' as part of {}",
 1884                                    &command.command,
 1885                                    describe_code_action(&action),
 1886                                );
 1887                                continue 'actions;
 1888                            }
 1889
 1890                            let mut project_transaction_command =
 1891                                lsp_store.update(cx, |this, _| {
 1892                                    this.as_local_mut()
 1893                                        .unwrap()
 1894                                        .last_workspace_edits_by_language_server
 1895                                        .remove(&server.server_id())
 1896                                        .unwrap_or_default()
 1897                                })?;
 1898
 1899                            if let Some(transaction) =
 1900                                project_transaction_command.0.remove(&buffer.handle)
 1901                            {
 1902                                zlog::trace!(
 1903                                    logger =>
 1904                                    "Successfully captured {} edits that resulted from command {}",
 1905                                    transaction.edit_ids.len(),
 1906                                    &command.command,
 1907                                );
 1908                                let transaction_id_project_transaction = transaction.id;
 1909                                buffer.handle.update(cx, |buffer, _| {
 1910                                    // it may have been removed from history if push_to_history was
 1911                                    // false in deserialize_workspace_edit. If so push it so we
 1912                                    // can merge it with the format transaction
 1913                                    // and pop the combined transaction off the history stack
 1914                                    // later if push_to_history is false
 1915                                    if buffer.get_transaction(transaction.id).is_none() {
 1916                                        buffer.push_transaction(transaction, Instant::now());
 1917                                    }
 1918                                    buffer.merge_transactions(
 1919                                        transaction_id_project_transaction,
 1920                                        formatting_transaction_id,
 1921                                    );
 1922                                })?;
 1923                            }
 1924
 1925                            if !project_transaction_command.0.is_empty() {
 1926                                let mut extra_buffers = String::new();
 1927                                for buffer in project_transaction_command.0.keys() {
 1928                                    buffer
 1929                                        .read_with(cx, |b, cx| {
 1930                                            if let Some(path) = b.project_path(cx) {
 1931                                                if !extra_buffers.is_empty() {
 1932                                                    extra_buffers.push_str(", ");
 1933                                                }
 1934                                                extra_buffers.push_str(path.path.as_unix_str());
 1935                                            }
 1936                                        })
 1937                                        .ok();
 1938                                }
 1939                                zlog::warn!(
 1940                                    logger =>
 1941                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1942                                    &command.command,
 1943                                    extra_buffers,
 1944                                );
 1945                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1946                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1947                                // add it so it's included, and merge it into the format transaction when its created later
 1948                            }
 1949                        }
 1950                    }
 1951                }
 1952            }
 1953        }
 1954
 1955        Ok(())
 1956    }
 1957
 1958    pub async fn format_ranges_via_lsp(
 1959        this: &WeakEntity<LspStore>,
 1960        buffer_handle: &Entity<Buffer>,
 1961        ranges: &[Range<Anchor>],
 1962        abs_path: &Path,
 1963        language_server: &Arc<LanguageServer>,
 1964        settings: &LanguageSettings,
 1965        cx: &mut AsyncApp,
 1966    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1967        let capabilities = &language_server.capabilities();
 1968        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1969        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1970            anyhow::bail!(
 1971                "{} language server does not support range formatting",
 1972                language_server.name()
 1973            );
 1974        }
 1975
 1976        let uri = file_path_to_lsp_url(abs_path)?;
 1977        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1978
 1979        let lsp_edits = {
 1980            let mut lsp_ranges = Vec::new();
 1981            this.update(cx, |_this, cx| {
 1982                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1983                // not have been sent to the language server. This seems like a fairly systemic
 1984                // issue, though, the resolution probably is not specific to formatting.
 1985                //
 1986                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1987                // LSP.
 1988                let snapshot = buffer_handle.read(cx).snapshot();
 1989                for range in ranges {
 1990                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1991                }
 1992                anyhow::Ok(())
 1993            })??;
 1994
 1995            let mut edits = None;
 1996            for range in lsp_ranges {
 1997                if let Some(mut edit) = language_server
 1998                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1999                        text_document: text_document.clone(),
 2000                        range,
 2001                        options: lsp_command::lsp_formatting_options(settings),
 2002                        work_done_progress_params: Default::default(),
 2003                    })
 2004                    .await
 2005                    .into_response()?
 2006                {
 2007                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2008                }
 2009            }
 2010            edits
 2011        };
 2012
 2013        if let Some(lsp_edits) = lsp_edits {
 2014            this.update(cx, |this, cx| {
 2015                this.as_local_mut().unwrap().edits_from_lsp(
 2016                    buffer_handle,
 2017                    lsp_edits,
 2018                    language_server.server_id(),
 2019                    None,
 2020                    cx,
 2021                )
 2022            })?
 2023            .await
 2024        } else {
 2025            Ok(Vec::with_capacity(0))
 2026        }
 2027    }
 2028
 2029    async fn format_via_lsp(
 2030        this: &WeakEntity<LspStore>,
 2031        buffer: &Entity<Buffer>,
 2032        abs_path: &Path,
 2033        language_server: &Arc<LanguageServer>,
 2034        settings: &LanguageSettings,
 2035        cx: &mut AsyncApp,
 2036    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2037        let logger = zlog::scoped!("lsp_format");
 2038        zlog::debug!(logger => "Formatting via LSP");
 2039
 2040        let uri = file_path_to_lsp_url(abs_path)?;
 2041        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2042        let capabilities = &language_server.capabilities();
 2043
 2044        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2045        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2046
 2047        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2048            let _timer = zlog::time!(logger => "format-full");
 2049            language_server
 2050                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2051                    text_document,
 2052                    options: lsp_command::lsp_formatting_options(settings),
 2053                    work_done_progress_params: Default::default(),
 2054                })
 2055                .await
 2056                .into_response()?
 2057        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2058            let _timer = zlog::time!(logger => "format-range");
 2059            let buffer_start = lsp::Position::new(0, 0);
 2060            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2061            language_server
 2062                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2063                    text_document: text_document.clone(),
 2064                    range: lsp::Range::new(buffer_start, buffer_end),
 2065                    options: lsp_command::lsp_formatting_options(settings),
 2066                    work_done_progress_params: Default::default(),
 2067                })
 2068                .await
 2069                .into_response()?
 2070        } else {
 2071            None
 2072        };
 2073
 2074        if let Some(lsp_edits) = lsp_edits {
 2075            this.update(cx, |this, cx| {
 2076                this.as_local_mut().unwrap().edits_from_lsp(
 2077                    buffer,
 2078                    lsp_edits,
 2079                    language_server.server_id(),
 2080                    None,
 2081                    cx,
 2082                )
 2083            })?
 2084            .await
 2085        } else {
 2086            Ok(Vec::with_capacity(0))
 2087        }
 2088    }
 2089
 2090    async fn format_via_external_command(
 2091        buffer: &FormattableBuffer,
 2092        command: &str,
 2093        arguments: Option<&[String]>,
 2094        cx: &mut AsyncApp,
 2095    ) -> Result<Option<Diff>> {
 2096        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2097            let file = File::from_dyn(buffer.file())?;
 2098            let worktree = file.worktree.read(cx);
 2099            let mut worktree_path = worktree.abs_path().to_path_buf();
 2100            if worktree.root_entry()?.is_file() {
 2101                worktree_path.pop();
 2102            }
 2103            Some(worktree_path)
 2104        })?;
 2105
 2106        let mut child = util::command::new_smol_command(command);
 2107
 2108        if let Some(buffer_env) = buffer.env.as_ref() {
 2109            child.envs(buffer_env);
 2110        }
 2111
 2112        if let Some(working_dir_path) = working_dir_path {
 2113            child.current_dir(working_dir_path);
 2114        }
 2115
 2116        if let Some(arguments) = arguments {
 2117            child.args(arguments.iter().map(|arg| {
 2118                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2119                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2120                } else {
 2121                    arg.replace("{buffer_path}", "Untitled")
 2122                }
 2123            }));
 2124        }
 2125
 2126        let mut child = child
 2127            .stdin(smol::process::Stdio::piped())
 2128            .stdout(smol::process::Stdio::piped())
 2129            .stderr(smol::process::Stdio::piped())
 2130            .spawn()?;
 2131
 2132        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2133        let text = buffer
 2134            .handle
 2135            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2136        for chunk in text.chunks() {
 2137            stdin.write_all(chunk.as_bytes()).await?;
 2138        }
 2139        stdin.flush().await?;
 2140
 2141        let output = child.output().await?;
 2142        anyhow::ensure!(
 2143            output.status.success(),
 2144            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2145            output.status.code(),
 2146            String::from_utf8_lossy(&output.stdout),
 2147            String::from_utf8_lossy(&output.stderr),
 2148        );
 2149
 2150        let stdout = String::from_utf8(output.stdout)?;
 2151        Ok(Some(
 2152            buffer
 2153                .handle
 2154                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2155                .await,
 2156        ))
 2157    }
 2158
 2159    async fn try_resolve_code_action(
 2160        lang_server: &LanguageServer,
 2161        action: &mut CodeAction,
 2162    ) -> anyhow::Result<()> {
 2163        match &mut action.lsp_action {
 2164            LspAction::Action(lsp_action) => {
 2165                if !action.resolved
 2166                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2167                    && lsp_action.data.is_some()
 2168                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2169                {
 2170                    *lsp_action = Box::new(
 2171                        lang_server
 2172                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2173                            .await
 2174                            .into_response()?,
 2175                    );
 2176                }
 2177            }
 2178            LspAction::CodeLens(lens) => {
 2179                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2180                    *lens = lang_server
 2181                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2182                        .await
 2183                        .into_response()?;
 2184                }
 2185            }
 2186            LspAction::Command(_) => {}
 2187        }
 2188
 2189        action.resolved = true;
 2190        anyhow::Ok(())
 2191    }
 2192
 2193    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2194        let buffer = buffer_handle.read(cx);
 2195
 2196        let file = buffer.file().cloned();
 2197
 2198        let Some(file) = File::from_dyn(file.as_ref()) else {
 2199            return;
 2200        };
 2201        if !file.is_local() {
 2202            return;
 2203        }
 2204        let path = ProjectPath::from_file(file, cx);
 2205        let worktree_id = file.worktree_id(cx);
 2206        let language = buffer.language().cloned();
 2207
 2208        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2209            for (server_id, diagnostics) in
 2210                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2211            {
 2212                self.update_buffer_diagnostics(
 2213                    buffer_handle,
 2214                    server_id,
 2215                    None,
 2216                    None,
 2217                    diagnostics,
 2218                    Vec::new(),
 2219                    cx,
 2220                )
 2221                .log_err();
 2222            }
 2223        }
 2224        let Some(language) = language else {
 2225            return;
 2226        };
 2227        let Some(snapshot) = self
 2228            .worktree_store
 2229            .read(cx)
 2230            .worktree_for_id(worktree_id, cx)
 2231            .map(|worktree| worktree.read(cx).snapshot())
 2232        else {
 2233            return;
 2234        };
 2235        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2236
 2237        for server_id in
 2238            self.lsp_tree
 2239                .get(path, language.name(), language.manifest(), &delegate, cx)
 2240        {
 2241            let server = self
 2242                .language_servers
 2243                .get(&server_id)
 2244                .and_then(|server_state| {
 2245                    if let LanguageServerState::Running { server, .. } = server_state {
 2246                        Some(server.clone())
 2247                    } else {
 2248                        None
 2249                    }
 2250                });
 2251            let server = match server {
 2252                Some(server) => server,
 2253                None => continue,
 2254            };
 2255
 2256            buffer_handle.update(cx, |buffer, cx| {
 2257                buffer.set_completion_triggers(
 2258                    server.server_id(),
 2259                    server
 2260                        .capabilities()
 2261                        .completion_provider
 2262                        .as_ref()
 2263                        .and_then(|provider| {
 2264                            provider
 2265                                .trigger_characters
 2266                                .as_ref()
 2267                                .map(|characters| characters.iter().cloned().collect())
 2268                        })
 2269                        .unwrap_or_default(),
 2270                    cx,
 2271                );
 2272            });
 2273        }
 2274    }
 2275
 2276    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2277        buffer.update(cx, |buffer, cx| {
 2278            let Some(language) = buffer.language() else {
 2279                return;
 2280            };
 2281            let path = ProjectPath {
 2282                worktree_id: old_file.worktree_id(cx),
 2283                path: old_file.path.clone(),
 2284            };
 2285            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2286                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2287                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2288            }
 2289        });
 2290    }
 2291
 2292    fn update_buffer_diagnostics(
 2293        &mut self,
 2294        buffer: &Entity<Buffer>,
 2295        server_id: LanguageServerId,
 2296        result_id: Option<String>,
 2297        version: Option<i32>,
 2298        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2299        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2300        cx: &mut Context<LspStore>,
 2301    ) -> Result<()> {
 2302        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2303            Ordering::Equal
 2304                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2305                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2306                .then_with(|| a.severity.cmp(&b.severity))
 2307                .then_with(|| a.message.cmp(&b.message))
 2308        }
 2309
 2310        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2311        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2312        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2313
 2314        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2315            Ordering::Equal
 2316                .then_with(|| a.range.start.cmp(&b.range.start))
 2317                .then_with(|| b.range.end.cmp(&a.range.end))
 2318                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2319        });
 2320
 2321        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2322
 2323        let edits_since_save = std::cell::LazyCell::new(|| {
 2324            let saved_version = buffer.read(cx).saved_version();
 2325            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2326        });
 2327
 2328        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2329
 2330        for (new_diagnostic, entry) in diagnostics {
 2331            let start;
 2332            let end;
 2333            if new_diagnostic && entry.diagnostic.is_disk_based {
 2334                // Some diagnostics are based on files on disk instead of buffers'
 2335                // current contents. Adjust these diagnostics' ranges to reflect
 2336                // any unsaved edits.
 2337                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2338                // and were properly adjusted on reuse.
 2339                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2340                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2341            } else {
 2342                start = entry.range.start;
 2343                end = entry.range.end;
 2344            }
 2345
 2346            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2347                ..snapshot.clip_point_utf16(end, Bias::Right);
 2348
 2349            // Expand empty ranges by one codepoint
 2350            if range.start == range.end {
 2351                // This will be go to the next boundary when being clipped
 2352                range.end.column += 1;
 2353                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2354                if range.start == range.end && range.end.column > 0 {
 2355                    range.start.column -= 1;
 2356                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2357                }
 2358            }
 2359
 2360            sanitized_diagnostics.push(DiagnosticEntry {
 2361                range,
 2362                diagnostic: entry.diagnostic,
 2363            });
 2364        }
 2365        drop(edits_since_save);
 2366
 2367        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2368        buffer.update(cx, |buffer, cx| {
 2369            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2370                self.buffer_pull_diagnostics_result_ids
 2371                    .entry(server_id)
 2372                    .or_default()
 2373                    .insert(abs_path, result_id);
 2374            }
 2375
 2376            buffer.update_diagnostics(server_id, set, cx)
 2377        });
 2378
 2379        Ok(())
 2380    }
 2381
 2382    fn register_language_server_for_invisible_worktree(
 2383        &mut self,
 2384        worktree: &Entity<Worktree>,
 2385        language_server_id: LanguageServerId,
 2386        cx: &mut App,
 2387    ) {
 2388        let worktree = worktree.read(cx);
 2389        let worktree_id = worktree.id();
 2390        debug_assert!(!worktree.is_visible());
 2391        let Some(mut origin_seed) = self
 2392            .language_server_ids
 2393            .iter()
 2394            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2395        else {
 2396            return;
 2397        };
 2398        origin_seed.worktree_id = worktree_id;
 2399        self.language_server_ids
 2400            .entry(origin_seed)
 2401            .or_insert_with(|| UnifiedLanguageServer {
 2402                id: language_server_id,
 2403                project_roots: Default::default(),
 2404            });
 2405    }
 2406
 2407    fn register_buffer_with_language_servers(
 2408        &mut self,
 2409        buffer_handle: &Entity<Buffer>,
 2410        only_register_servers: HashSet<LanguageServerSelector>,
 2411        cx: &mut Context<LspStore>,
 2412    ) {
 2413        let buffer = buffer_handle.read(cx);
 2414        let buffer_id = buffer.remote_id();
 2415
 2416        let Some(file) = File::from_dyn(buffer.file()) else {
 2417            return;
 2418        };
 2419        if !file.is_local() {
 2420            return;
 2421        }
 2422
 2423        let abs_path = file.abs_path(cx);
 2424        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2425            return;
 2426        };
 2427        let initial_snapshot = buffer.text_snapshot();
 2428        let worktree_id = file.worktree_id(cx);
 2429
 2430        let Some(language) = buffer.language().cloned() else {
 2431            return;
 2432        };
 2433        let path: Arc<RelPath> = file
 2434            .path()
 2435            .parent()
 2436            .map(Arc::from)
 2437            .unwrap_or_else(|| file.path().clone());
 2438        let Some(worktree) = self
 2439            .worktree_store
 2440            .read(cx)
 2441            .worktree_for_id(worktree_id, cx)
 2442        else {
 2443            return;
 2444        };
 2445        let language_name = language.name();
 2446        let (reused, delegate, servers) = self
 2447            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2448            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2449            .unwrap_or_else(|| {
 2450                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2451                let delegate: Arc<dyn ManifestDelegate> =
 2452                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2453
 2454                let servers = self
 2455                    .lsp_tree
 2456                    .walk(
 2457                        ProjectPath { worktree_id, path },
 2458                        language.name(),
 2459                        language.manifest(),
 2460                        &delegate,
 2461                        cx,
 2462                    )
 2463                    .collect::<Vec<_>>();
 2464                (false, lsp_delegate, servers)
 2465            });
 2466        let servers_and_adapters = servers
 2467            .into_iter()
 2468            .filter_map(|server_node| {
 2469                if reused && server_node.server_id().is_none() {
 2470                    return None;
 2471                }
 2472                if !only_register_servers.is_empty() {
 2473                    if let Some(server_id) = server_node.server_id()
 2474                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2475                    {
 2476                        return None;
 2477                    }
 2478                    if let Some(name) = server_node.name()
 2479                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2480                    {
 2481                        return None;
 2482                    }
 2483                }
 2484
 2485                let server_id = server_node.server_id_or_init(|disposition| {
 2486                    let path = &disposition.path;
 2487
 2488                    {
 2489                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2490
 2491                        let server_id = self.get_or_insert_language_server(
 2492                            &worktree,
 2493                            delegate.clone(),
 2494                            disposition,
 2495                            &language_name,
 2496                            cx,
 2497                        );
 2498
 2499                        if let Some(state) = self.language_servers.get(&server_id)
 2500                            && let Ok(uri) = uri
 2501                        {
 2502                            state.add_workspace_folder(uri);
 2503                        };
 2504                        server_id
 2505                    }
 2506                })?;
 2507                let server_state = self.language_servers.get(&server_id)?;
 2508                if let LanguageServerState::Running {
 2509                    server, adapter, ..
 2510                } = server_state
 2511                {
 2512                    Some((server.clone(), adapter.clone()))
 2513                } else {
 2514                    None
 2515                }
 2516            })
 2517            .collect::<Vec<_>>();
 2518        for (server, adapter) in servers_and_adapters {
 2519            buffer_handle.update(cx, |buffer, cx| {
 2520                buffer.set_completion_triggers(
 2521                    server.server_id(),
 2522                    server
 2523                        .capabilities()
 2524                        .completion_provider
 2525                        .as_ref()
 2526                        .and_then(|provider| {
 2527                            provider
 2528                                .trigger_characters
 2529                                .as_ref()
 2530                                .map(|characters| characters.iter().cloned().collect())
 2531                        })
 2532                        .unwrap_or_default(),
 2533                    cx,
 2534                );
 2535            });
 2536
 2537            let snapshot = LspBufferSnapshot {
 2538                version: 0,
 2539                snapshot: initial_snapshot.clone(),
 2540            };
 2541
 2542            let mut registered = false;
 2543            self.buffer_snapshots
 2544                .entry(buffer_id)
 2545                .or_default()
 2546                .entry(server.server_id())
 2547                .or_insert_with(|| {
 2548                    registered = true;
 2549                    server.register_buffer(
 2550                        uri.clone(),
 2551                        adapter.language_id(&language.name()),
 2552                        0,
 2553                        initial_snapshot.text(),
 2554                    );
 2555
 2556                    vec![snapshot]
 2557                });
 2558
 2559            self.buffers_opened_in_servers
 2560                .entry(buffer_id)
 2561                .or_default()
 2562                .insert(server.server_id());
 2563            if registered {
 2564                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2565                    language_server_id: server.server_id(),
 2566                    name: None,
 2567                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2568                        proto::RegisteredForBuffer {
 2569                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2570                            buffer_id: buffer_id.to_proto(),
 2571                        },
 2572                    ),
 2573                });
 2574            }
 2575        }
 2576    }
 2577
 2578    fn reuse_existing_language_server<'lang_name>(
 2579        &self,
 2580        server_tree: &LanguageServerTree,
 2581        worktree: &Entity<Worktree>,
 2582        language_name: &'lang_name LanguageName,
 2583        cx: &mut App,
 2584    ) -> Option<(
 2585        Arc<LocalLspAdapterDelegate>,
 2586        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2587    )> {
 2588        if worktree.read(cx).is_visible() {
 2589            return None;
 2590        }
 2591
 2592        let worktree_store = self.worktree_store.read(cx);
 2593        let servers = server_tree
 2594            .instances
 2595            .iter()
 2596            .filter(|(worktree_id, _)| {
 2597                worktree_store
 2598                    .worktree_for_id(**worktree_id, cx)
 2599                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2600            })
 2601            .flat_map(|(worktree_id, servers)| {
 2602                servers
 2603                    .roots
 2604                    .iter()
 2605                    .flat_map(|(_, language_servers)| language_servers)
 2606                    .map(move |(_, (server_node, server_languages))| {
 2607                        (worktree_id, server_node, server_languages)
 2608                    })
 2609                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2610                    .map(|(worktree_id, server_node, _)| {
 2611                        (
 2612                            *worktree_id,
 2613                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2614                        )
 2615                    })
 2616            })
 2617            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2618                acc.entry(worktree_id)
 2619                    .or_insert_with(Vec::new)
 2620                    .push(server_node);
 2621                acc
 2622            })
 2623            .into_values()
 2624            .max_by_key(|servers| servers.len())?;
 2625
 2626        let worktree_id = worktree.read(cx).id();
 2627        let apply = move |tree: &mut LanguageServerTree| {
 2628            for server_node in &servers {
 2629                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2630            }
 2631            servers
 2632        };
 2633
 2634        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2635        Some((delegate, apply))
 2636    }
 2637
 2638    pub(crate) fn unregister_old_buffer_from_language_servers(
 2639        &mut self,
 2640        buffer: &Entity<Buffer>,
 2641        old_file: &File,
 2642        cx: &mut App,
 2643    ) {
 2644        let old_path = match old_file.as_local() {
 2645            Some(local) => local.abs_path(cx),
 2646            None => return,
 2647        };
 2648
 2649        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2650            debug_panic!("{old_path:?} is not parseable as an URI");
 2651            return;
 2652        };
 2653        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2654    }
 2655
 2656    pub(crate) fn unregister_buffer_from_language_servers(
 2657        &mut self,
 2658        buffer: &Entity<Buffer>,
 2659        file_url: &lsp::Uri,
 2660        cx: &mut App,
 2661    ) {
 2662        buffer.update(cx, |buffer, cx| {
 2663            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2664
 2665            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2666                language_server.unregister_buffer(file_url.clone());
 2667            }
 2668        });
 2669    }
 2670
 2671    fn buffer_snapshot_for_lsp_version(
 2672        &mut self,
 2673        buffer: &Entity<Buffer>,
 2674        server_id: LanguageServerId,
 2675        version: Option<i32>,
 2676        cx: &App,
 2677    ) -> Result<TextBufferSnapshot> {
 2678        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2679
 2680        if let Some(version) = version {
 2681            let buffer_id = buffer.read(cx).remote_id();
 2682            let snapshots = if let Some(snapshots) = self
 2683                .buffer_snapshots
 2684                .get_mut(&buffer_id)
 2685                .and_then(|m| m.get_mut(&server_id))
 2686            {
 2687                snapshots
 2688            } else if version == 0 {
 2689                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2690                // We detect this case and treat it as if the version was `None`.
 2691                return Ok(buffer.read(cx).text_snapshot());
 2692            } else {
 2693                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2694            };
 2695
 2696            let found_snapshot = snapshots
 2697                    .binary_search_by_key(&version, |e| e.version)
 2698                    .map(|ix| snapshots[ix].snapshot.clone())
 2699                    .map_err(|_| {
 2700                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2701                    })?;
 2702
 2703            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2704            Ok(found_snapshot)
 2705        } else {
 2706            Ok((buffer.read(cx)).text_snapshot())
 2707        }
 2708    }
 2709
 2710    async fn get_server_code_actions_from_action_kinds(
 2711        lsp_store: &WeakEntity<LspStore>,
 2712        language_server_id: LanguageServerId,
 2713        code_action_kinds: Vec<lsp::CodeActionKind>,
 2714        buffer: &Entity<Buffer>,
 2715        cx: &mut AsyncApp,
 2716    ) -> Result<Vec<CodeAction>> {
 2717        let actions = lsp_store
 2718            .update(cx, move |this, cx| {
 2719                let request = GetCodeActions {
 2720                    range: text::Anchor::MIN..text::Anchor::MAX,
 2721                    kinds: Some(code_action_kinds),
 2722                };
 2723                let server = LanguageServerToQuery::Other(language_server_id);
 2724                this.request_lsp(buffer.clone(), server, request, cx)
 2725            })?
 2726            .await?;
 2727        Ok(actions)
 2728    }
 2729
 2730    pub async fn execute_code_actions_on_server(
 2731        lsp_store: &WeakEntity<LspStore>,
 2732        language_server: &Arc<LanguageServer>,
 2733
 2734        actions: Vec<CodeAction>,
 2735        push_to_history: bool,
 2736        project_transaction: &mut ProjectTransaction,
 2737        cx: &mut AsyncApp,
 2738    ) -> anyhow::Result<()> {
 2739        for mut action in actions {
 2740            Self::try_resolve_code_action(language_server, &mut action)
 2741                .await
 2742                .context("resolving a formatting code action")?;
 2743
 2744            if let Some(edit) = action.lsp_action.edit() {
 2745                if edit.changes.is_none() && edit.document_changes.is_none() {
 2746                    continue;
 2747                }
 2748
 2749                let new = Self::deserialize_workspace_edit(
 2750                    lsp_store.upgrade().context("project dropped")?,
 2751                    edit.clone(),
 2752                    push_to_history,
 2753                    language_server.clone(),
 2754                    cx,
 2755                )
 2756                .await?;
 2757                project_transaction.0.extend(new.0);
 2758            }
 2759
 2760            if let Some(command) = action.lsp_action.command() {
 2761                let server_capabilities = language_server.capabilities();
 2762                let available_commands = server_capabilities
 2763                    .execute_command_provider
 2764                    .as_ref()
 2765                    .map(|options| options.commands.as_slice())
 2766                    .unwrap_or_default();
 2767                if available_commands.contains(&command.command) {
 2768                    lsp_store.update(cx, |lsp_store, _| {
 2769                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2770                            mode.last_workspace_edits_by_language_server
 2771                                .remove(&language_server.server_id());
 2772                        }
 2773                    })?;
 2774
 2775                    language_server
 2776                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2777                            command: command.command.clone(),
 2778                            arguments: command.arguments.clone().unwrap_or_default(),
 2779                            ..Default::default()
 2780                        })
 2781                        .await
 2782                        .into_response()
 2783                        .context("execute command")?;
 2784
 2785                    lsp_store.update(cx, |this, _| {
 2786                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2787                            project_transaction.0.extend(
 2788                                mode.last_workspace_edits_by_language_server
 2789                                    .remove(&language_server.server_id())
 2790                                    .unwrap_or_default()
 2791                                    .0,
 2792                            )
 2793                        }
 2794                    })?;
 2795                } else {
 2796                    log::warn!(
 2797                        "Cannot execute a command {} not listed in the language server capabilities",
 2798                        command.command
 2799                    )
 2800                }
 2801            }
 2802        }
 2803        Ok(())
 2804    }
 2805
 2806    pub async fn deserialize_text_edits(
 2807        this: Entity<LspStore>,
 2808        buffer_to_edit: Entity<Buffer>,
 2809        edits: Vec<lsp::TextEdit>,
 2810        push_to_history: bool,
 2811        _: Arc<CachedLspAdapter>,
 2812        language_server: Arc<LanguageServer>,
 2813        cx: &mut AsyncApp,
 2814    ) -> Result<Option<Transaction>> {
 2815        let edits = this
 2816            .update(cx, |this, cx| {
 2817                this.as_local_mut().unwrap().edits_from_lsp(
 2818                    &buffer_to_edit,
 2819                    edits,
 2820                    language_server.server_id(),
 2821                    None,
 2822                    cx,
 2823                )
 2824            })?
 2825            .await?;
 2826
 2827        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2828            buffer.finalize_last_transaction();
 2829            buffer.start_transaction();
 2830            for (range, text) in edits {
 2831                buffer.edit([(range, text)], None, cx);
 2832            }
 2833
 2834            if buffer.end_transaction(cx).is_some() {
 2835                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2836                if !push_to_history {
 2837                    buffer.forget_transaction(transaction.id);
 2838                }
 2839                Some(transaction)
 2840            } else {
 2841                None
 2842            }
 2843        })?;
 2844
 2845        Ok(transaction)
 2846    }
 2847
 2848    #[allow(clippy::type_complexity)]
 2849    pub(crate) fn edits_from_lsp(
 2850        &mut self,
 2851        buffer: &Entity<Buffer>,
 2852        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2853        server_id: LanguageServerId,
 2854        version: Option<i32>,
 2855        cx: &mut Context<LspStore>,
 2856    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2857        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2858        cx.background_spawn(async move {
 2859            let snapshot = snapshot?;
 2860            let mut lsp_edits = lsp_edits
 2861                .into_iter()
 2862                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2863                .collect::<Vec<_>>();
 2864
 2865            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2866
 2867            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2868            let mut edits = Vec::new();
 2869            while let Some((range, mut new_text)) = lsp_edits.next() {
 2870                // Clip invalid ranges provided by the language server.
 2871                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2872                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2873
 2874                // Combine any LSP edits that are adjacent.
 2875                //
 2876                // Also, combine LSP edits that are separated from each other by only
 2877                // a newline. This is important because for some code actions,
 2878                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2879                // are separated by unchanged newline characters.
 2880                //
 2881                // In order for the diffing logic below to work properly, any edits that
 2882                // cancel each other out must be combined into one.
 2883                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2884                    if next_range.start.0 > range.end {
 2885                        if next_range.start.0.row > range.end.row + 1
 2886                            || next_range.start.0.column > 0
 2887                            || snapshot.clip_point_utf16(
 2888                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2889                                Bias::Left,
 2890                            ) > range.end
 2891                        {
 2892                            break;
 2893                        }
 2894                        new_text.push('\n');
 2895                    }
 2896                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2897                    new_text.push_str(next_text);
 2898                    lsp_edits.next();
 2899                }
 2900
 2901                // For multiline edits, perform a diff of the old and new text so that
 2902                // we can identify the changes more precisely, preserving the locations
 2903                // of any anchors positioned in the unchanged regions.
 2904                if range.end.row > range.start.row {
 2905                    let offset = range.start.to_offset(&snapshot);
 2906                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2907                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2908                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2909                        (
 2910                            snapshot.anchor_after(offset + range.start)
 2911                                ..snapshot.anchor_before(offset + range.end),
 2912                            replacement,
 2913                        )
 2914                    }));
 2915                } else if range.end == range.start {
 2916                    let anchor = snapshot.anchor_after(range.start);
 2917                    edits.push((anchor..anchor, new_text.into()));
 2918                } else {
 2919                    let edit_start = snapshot.anchor_after(range.start);
 2920                    let edit_end = snapshot.anchor_before(range.end);
 2921                    edits.push((edit_start..edit_end, new_text.into()));
 2922                }
 2923            }
 2924
 2925            Ok(edits)
 2926        })
 2927    }
 2928
 2929    pub(crate) async fn deserialize_workspace_edit(
 2930        this: Entity<LspStore>,
 2931        edit: lsp::WorkspaceEdit,
 2932        push_to_history: bool,
 2933        language_server: Arc<LanguageServer>,
 2934        cx: &mut AsyncApp,
 2935    ) -> Result<ProjectTransaction> {
 2936        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2937
 2938        let mut operations = Vec::new();
 2939        if let Some(document_changes) = edit.document_changes {
 2940            match document_changes {
 2941                lsp::DocumentChanges::Edits(edits) => {
 2942                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2943                }
 2944                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2945            }
 2946        } else if let Some(changes) = edit.changes {
 2947            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2948                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2949                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2950                        uri,
 2951                        version: None,
 2952                    },
 2953                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2954                })
 2955            }));
 2956        }
 2957
 2958        let mut project_transaction = ProjectTransaction::default();
 2959        for operation in operations {
 2960            match operation {
 2961                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2962                    let abs_path = op
 2963                        .uri
 2964                        .to_file_path()
 2965                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2966
 2967                    if let Some(parent_path) = abs_path.parent() {
 2968                        fs.create_dir(parent_path).await?;
 2969                    }
 2970                    if abs_path.ends_with("/") {
 2971                        fs.create_dir(&abs_path).await?;
 2972                    } else {
 2973                        fs.create_file(
 2974                            &abs_path,
 2975                            op.options
 2976                                .map(|options| fs::CreateOptions {
 2977                                    overwrite: options.overwrite.unwrap_or(false),
 2978                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2979                                })
 2980                                .unwrap_or_default(),
 2981                        )
 2982                        .await?;
 2983                    }
 2984                }
 2985
 2986                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2987                    let source_abs_path = op
 2988                        .old_uri
 2989                        .to_file_path()
 2990                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2991                    let target_abs_path = op
 2992                        .new_uri
 2993                        .to_file_path()
 2994                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2995                    fs.rename(
 2996                        &source_abs_path,
 2997                        &target_abs_path,
 2998                        op.options
 2999                            .map(|options| fs::RenameOptions {
 3000                                overwrite: options.overwrite.unwrap_or(false),
 3001                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3002                            })
 3003                            .unwrap_or_default(),
 3004                    )
 3005                    .await?;
 3006                }
 3007
 3008                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3009                    let abs_path = op
 3010                        .uri
 3011                        .to_file_path()
 3012                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3013                    let options = op
 3014                        .options
 3015                        .map(|options| fs::RemoveOptions {
 3016                            recursive: options.recursive.unwrap_or(false),
 3017                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3018                        })
 3019                        .unwrap_or_default();
 3020                    if abs_path.ends_with("/") {
 3021                        fs.remove_dir(&abs_path, options).await?;
 3022                    } else {
 3023                        fs.remove_file(&abs_path, options).await?;
 3024                    }
 3025                }
 3026
 3027                lsp::DocumentChangeOperation::Edit(op) => {
 3028                    let buffer_to_edit = this
 3029                        .update(cx, |this, cx| {
 3030                            this.open_local_buffer_via_lsp(
 3031                                op.text_document.uri.clone(),
 3032                                language_server.server_id(),
 3033                                cx,
 3034                            )
 3035                        })?
 3036                        .await?;
 3037
 3038                    let edits = this
 3039                        .update(cx, |this, cx| {
 3040                            let path = buffer_to_edit.read(cx).project_path(cx);
 3041                            let active_entry = this.active_entry;
 3042                            let is_active_entry = path.is_some_and(|project_path| {
 3043                                this.worktree_store
 3044                                    .read(cx)
 3045                                    .entry_for_path(&project_path, cx)
 3046                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3047                            });
 3048                            let local = this.as_local_mut().unwrap();
 3049
 3050                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3051                            for edit in op.edits {
 3052                                match edit {
 3053                                    Edit::Plain(edit) => {
 3054                                        if !edits.contains(&edit) {
 3055                                            edits.push(edit)
 3056                                        }
 3057                                    }
 3058                                    Edit::Annotated(edit) => {
 3059                                        if !edits.contains(&edit.text_edit) {
 3060                                            edits.push(edit.text_edit)
 3061                                        }
 3062                                    }
 3063                                    Edit::Snippet(edit) => {
 3064                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3065                                        else {
 3066                                            continue;
 3067                                        };
 3068
 3069                                        if is_active_entry {
 3070                                            snippet_edits.push((edit.range, snippet));
 3071                                        } else {
 3072                                            // Since this buffer is not focused, apply a normal edit.
 3073                                            let new_edit = TextEdit {
 3074                                                range: edit.range,
 3075                                                new_text: snippet.text,
 3076                                            };
 3077                                            if !edits.contains(&new_edit) {
 3078                                                edits.push(new_edit);
 3079                                            }
 3080                                        }
 3081                                    }
 3082                                }
 3083                            }
 3084                            if !snippet_edits.is_empty() {
 3085                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3086                                let version = if let Some(buffer_version) = op.text_document.version
 3087                                {
 3088                                    local
 3089                                        .buffer_snapshot_for_lsp_version(
 3090                                            &buffer_to_edit,
 3091                                            language_server.server_id(),
 3092                                            Some(buffer_version),
 3093                                            cx,
 3094                                        )
 3095                                        .ok()
 3096                                        .map(|snapshot| snapshot.version)
 3097                                } else {
 3098                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3099                                };
 3100
 3101                                let most_recent_edit =
 3102                                    version.and_then(|version| version.most_recent());
 3103                                // Check if the edit that triggered that edit has been made by this participant.
 3104
 3105                                if let Some(most_recent_edit) = most_recent_edit {
 3106                                    cx.emit(LspStoreEvent::SnippetEdit {
 3107                                        buffer_id,
 3108                                        edits: snippet_edits,
 3109                                        most_recent_edit,
 3110                                    });
 3111                                }
 3112                            }
 3113
 3114                            local.edits_from_lsp(
 3115                                &buffer_to_edit,
 3116                                edits,
 3117                                language_server.server_id(),
 3118                                op.text_document.version,
 3119                                cx,
 3120                            )
 3121                        })?
 3122                        .await?;
 3123
 3124                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3125                        buffer.finalize_last_transaction();
 3126                        buffer.start_transaction();
 3127                        for (range, text) in edits {
 3128                            buffer.edit([(range, text)], None, cx);
 3129                        }
 3130
 3131                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3132                            if push_to_history {
 3133                                buffer.finalize_last_transaction();
 3134                                buffer.get_transaction(transaction_id).cloned()
 3135                            } else {
 3136                                buffer.forget_transaction(transaction_id)
 3137                            }
 3138                        })
 3139                    })?;
 3140                    if let Some(transaction) = transaction {
 3141                        project_transaction.0.insert(buffer_to_edit, transaction);
 3142                    }
 3143                }
 3144            }
 3145        }
 3146
 3147        Ok(project_transaction)
 3148    }
 3149
 3150    async fn on_lsp_workspace_edit(
 3151        this: WeakEntity<LspStore>,
 3152        params: lsp::ApplyWorkspaceEditParams,
 3153        server_id: LanguageServerId,
 3154        cx: &mut AsyncApp,
 3155    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3156        let this = this.upgrade().context("project project closed")?;
 3157        let language_server = this
 3158            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3159            .context("language server not found")?;
 3160        let transaction = Self::deserialize_workspace_edit(
 3161            this.clone(),
 3162            params.edit,
 3163            true,
 3164            language_server.clone(),
 3165            cx,
 3166        )
 3167        .await
 3168        .log_err();
 3169        this.update(cx, |this, _| {
 3170            if let Some(transaction) = transaction {
 3171                this.as_local_mut()
 3172                    .unwrap()
 3173                    .last_workspace_edits_by_language_server
 3174                    .insert(server_id, transaction);
 3175            }
 3176        })?;
 3177        Ok(lsp::ApplyWorkspaceEditResponse {
 3178            applied: true,
 3179            failed_change: None,
 3180            failure_reason: None,
 3181        })
 3182    }
 3183
 3184    fn remove_worktree(
 3185        &mut self,
 3186        id_to_remove: WorktreeId,
 3187        cx: &mut Context<LspStore>,
 3188    ) -> Vec<LanguageServerId> {
 3189        self.diagnostics.remove(&id_to_remove);
 3190        self.prettier_store.update(cx, |prettier_store, cx| {
 3191            prettier_store.remove_worktree(id_to_remove, cx);
 3192        });
 3193
 3194        let mut servers_to_remove = BTreeSet::default();
 3195        let mut servers_to_preserve = HashSet::default();
 3196        for (seed, state) in &self.language_server_ids {
 3197            if seed.worktree_id == id_to_remove {
 3198                servers_to_remove.insert(state.id);
 3199            } else {
 3200                servers_to_preserve.insert(state.id);
 3201            }
 3202        }
 3203        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3204        self.language_server_ids
 3205            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3206        for server_id_to_remove in &servers_to_remove {
 3207            self.language_server_watched_paths
 3208                .remove(server_id_to_remove);
 3209            self.language_server_paths_watched_for_rename
 3210                .remove(server_id_to_remove);
 3211            self.last_workspace_edits_by_language_server
 3212                .remove(server_id_to_remove);
 3213            self.language_servers.remove(server_id_to_remove);
 3214            self.buffer_pull_diagnostics_result_ids
 3215                .remove(server_id_to_remove);
 3216            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3217                buffer_servers.remove(server_id_to_remove);
 3218            }
 3219            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3220        }
 3221        servers_to_remove.into_iter().collect()
 3222    }
 3223
 3224    fn rebuild_watched_paths_inner<'a>(
 3225        &'a self,
 3226        language_server_id: LanguageServerId,
 3227        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3228        cx: &mut Context<LspStore>,
 3229    ) -> LanguageServerWatchedPathsBuilder {
 3230        let worktrees = self
 3231            .worktree_store
 3232            .read(cx)
 3233            .worktrees()
 3234            .filter_map(|worktree| {
 3235                self.language_servers_for_worktree(worktree.read(cx).id())
 3236                    .find(|server| server.server_id() == language_server_id)
 3237                    .map(|_| worktree)
 3238            })
 3239            .collect::<Vec<_>>();
 3240
 3241        let mut worktree_globs = HashMap::default();
 3242        let mut abs_globs = HashMap::default();
 3243        log::trace!(
 3244            "Processing new watcher paths for language server with id {}",
 3245            language_server_id
 3246        );
 3247
 3248        for watcher in watchers {
 3249            if let Some((worktree, literal_prefix, pattern)) =
 3250                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3251            {
 3252                worktree.update(cx, |worktree, _| {
 3253                    if let Some((tree, glob)) =
 3254                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3255                    {
 3256                        tree.add_path_prefix_to_scan(literal_prefix);
 3257                        worktree_globs
 3258                            .entry(tree.id())
 3259                            .or_insert_with(GlobSetBuilder::new)
 3260                            .add(glob);
 3261                    }
 3262                });
 3263            } else {
 3264                let (path, pattern) = match &watcher.glob_pattern {
 3265                    lsp::GlobPattern::String(s) => {
 3266                        let watcher_path = SanitizedPath::new(s);
 3267                        let path = glob_literal_prefix(watcher_path.as_path());
 3268                        let pattern = watcher_path
 3269                            .as_path()
 3270                            .strip_prefix(&path)
 3271                            .map(|p| p.to_string_lossy().into_owned())
 3272                            .unwrap_or_else(|e| {
 3273                                debug_panic!(
 3274                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3275                                    s,
 3276                                    path.display(),
 3277                                    e
 3278                                );
 3279                                watcher_path.as_path().to_string_lossy().into_owned()
 3280                            });
 3281                        (path, pattern)
 3282                    }
 3283                    lsp::GlobPattern::Relative(rp) => {
 3284                        let Ok(mut base_uri) = match &rp.base_uri {
 3285                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3286                            lsp::OneOf::Right(base_uri) => base_uri,
 3287                        }
 3288                        .to_file_path() else {
 3289                            continue;
 3290                        };
 3291
 3292                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3293                        let pattern = Path::new(&rp.pattern)
 3294                            .strip_prefix(&path)
 3295                            .map(|p| p.to_string_lossy().into_owned())
 3296                            .unwrap_or_else(|e| {
 3297                                debug_panic!(
 3298                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3299                                    rp.pattern,
 3300                                    path.display(),
 3301                                    e
 3302                                );
 3303                                rp.pattern.clone()
 3304                            });
 3305                        base_uri.push(path);
 3306                        (base_uri, pattern)
 3307                    }
 3308                };
 3309
 3310                if let Some(glob) = Glob::new(&pattern).log_err() {
 3311                    if !path
 3312                        .components()
 3313                        .any(|c| matches!(c, path::Component::Normal(_)))
 3314                    {
 3315                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3316                        // rather than adding a new watcher for `/`.
 3317                        for worktree in &worktrees {
 3318                            worktree_globs
 3319                                .entry(worktree.read(cx).id())
 3320                                .or_insert_with(GlobSetBuilder::new)
 3321                                .add(glob.clone());
 3322                        }
 3323                    } else {
 3324                        abs_globs
 3325                            .entry(path.into())
 3326                            .or_insert_with(GlobSetBuilder::new)
 3327                            .add(glob);
 3328                    }
 3329                }
 3330            }
 3331        }
 3332
 3333        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3334        for (worktree_id, builder) in worktree_globs {
 3335            if let Ok(globset) = builder.build() {
 3336                watch_builder.watch_worktree(worktree_id, globset);
 3337            }
 3338        }
 3339        for (abs_path, builder) in abs_globs {
 3340            if let Ok(globset) = builder.build() {
 3341                watch_builder.watch_abs_path(abs_path, globset);
 3342            }
 3343        }
 3344        watch_builder
 3345    }
 3346
 3347    fn worktree_and_path_for_file_watcher(
 3348        worktrees: &[Entity<Worktree>],
 3349        watcher: &FileSystemWatcher,
 3350        cx: &App,
 3351    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3352        worktrees.iter().find_map(|worktree| {
 3353            let tree = worktree.read(cx);
 3354            let worktree_root_path = tree.abs_path();
 3355            let path_style = tree.path_style();
 3356            match &watcher.glob_pattern {
 3357                lsp::GlobPattern::String(s) => {
 3358                    let watcher_path = SanitizedPath::new(s);
 3359                    let relative = watcher_path
 3360                        .as_path()
 3361                        .strip_prefix(&worktree_root_path)
 3362                        .ok()?;
 3363                    let literal_prefix = glob_literal_prefix(relative);
 3364                    Some((
 3365                        worktree.clone(),
 3366                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3367                        relative.to_string_lossy().into_owned(),
 3368                    ))
 3369                }
 3370                lsp::GlobPattern::Relative(rp) => {
 3371                    let base_uri = match &rp.base_uri {
 3372                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3373                        lsp::OneOf::Right(base_uri) => base_uri,
 3374                    }
 3375                    .to_file_path()
 3376                    .ok()?;
 3377                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3378                    let mut literal_prefix = relative.to_owned();
 3379                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3380                    Some((
 3381                        worktree.clone(),
 3382                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3383                        rp.pattern.clone(),
 3384                    ))
 3385                }
 3386            }
 3387        })
 3388    }
 3389
 3390    fn rebuild_watched_paths(
 3391        &mut self,
 3392        language_server_id: LanguageServerId,
 3393        cx: &mut Context<LspStore>,
 3394    ) {
 3395        let Some(registrations) = self
 3396            .language_server_dynamic_registrations
 3397            .get(&language_server_id)
 3398        else {
 3399            return;
 3400        };
 3401
 3402        let watch_builder = self.rebuild_watched_paths_inner(
 3403            language_server_id,
 3404            registrations.did_change_watched_files.values().flatten(),
 3405            cx,
 3406        );
 3407        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3408        self.language_server_watched_paths
 3409            .insert(language_server_id, watcher);
 3410
 3411        cx.notify();
 3412    }
 3413
 3414    fn on_lsp_did_change_watched_files(
 3415        &mut self,
 3416        language_server_id: LanguageServerId,
 3417        registration_id: &str,
 3418        params: DidChangeWatchedFilesRegistrationOptions,
 3419        cx: &mut Context<LspStore>,
 3420    ) {
 3421        let registrations = self
 3422            .language_server_dynamic_registrations
 3423            .entry(language_server_id)
 3424            .or_default();
 3425
 3426        registrations
 3427            .did_change_watched_files
 3428            .insert(registration_id.to_string(), params.watchers);
 3429
 3430        self.rebuild_watched_paths(language_server_id, cx);
 3431    }
 3432
 3433    fn on_lsp_unregister_did_change_watched_files(
 3434        &mut self,
 3435        language_server_id: LanguageServerId,
 3436        registration_id: &str,
 3437        cx: &mut Context<LspStore>,
 3438    ) {
 3439        let registrations = self
 3440            .language_server_dynamic_registrations
 3441            .entry(language_server_id)
 3442            .or_default();
 3443
 3444        if registrations
 3445            .did_change_watched_files
 3446            .remove(registration_id)
 3447            .is_some()
 3448        {
 3449            log::info!(
 3450                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3451                language_server_id,
 3452                registration_id
 3453            );
 3454        } else {
 3455            log::warn!(
 3456                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3457                language_server_id,
 3458                registration_id
 3459            );
 3460        }
 3461
 3462        self.rebuild_watched_paths(language_server_id, cx);
 3463    }
 3464
 3465    async fn initialization_options_for_adapter(
 3466        adapter: Arc<dyn LspAdapter>,
 3467        delegate: &Arc<dyn LspAdapterDelegate>,
 3468    ) -> Result<Option<serde_json::Value>> {
 3469        let Some(mut initialization_config) =
 3470            adapter.clone().initialization_options(delegate).await?
 3471        else {
 3472            return Ok(None);
 3473        };
 3474
 3475        for other_adapter in delegate.registered_lsp_adapters() {
 3476            if other_adapter.name() == adapter.name() {
 3477                continue;
 3478            }
 3479            if let Ok(Some(target_config)) = other_adapter
 3480                .clone()
 3481                .additional_initialization_options(adapter.name(), delegate)
 3482                .await
 3483            {
 3484                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3485            }
 3486        }
 3487
 3488        Ok(Some(initialization_config))
 3489    }
 3490
 3491    async fn workspace_configuration_for_adapter(
 3492        adapter: Arc<dyn LspAdapter>,
 3493        delegate: &Arc<dyn LspAdapterDelegate>,
 3494        toolchain: Option<Toolchain>,
 3495        cx: &mut AsyncApp,
 3496    ) -> Result<serde_json::Value> {
 3497        let mut workspace_config = adapter
 3498            .clone()
 3499            .workspace_configuration(delegate, toolchain, cx)
 3500            .await?;
 3501
 3502        for other_adapter in delegate.registered_lsp_adapters() {
 3503            if other_adapter.name() == adapter.name() {
 3504                continue;
 3505            }
 3506            if let Ok(Some(target_config)) = other_adapter
 3507                .clone()
 3508                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3509                .await
 3510            {
 3511                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3512            }
 3513        }
 3514
 3515        Ok(workspace_config)
 3516    }
 3517
 3518    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3519        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3520            Some(server.clone())
 3521        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3522            Some(Arc::clone(server))
 3523        } else {
 3524            None
 3525        }
 3526    }
 3527}
 3528
 3529fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3530    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3531        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3532            language_server_id: server.server_id(),
 3533            name: Some(server.name()),
 3534            message: proto::update_language_server::Variant::MetadataUpdated(
 3535                proto::ServerMetadataUpdated {
 3536                    capabilities: Some(capabilities),
 3537                },
 3538            ),
 3539        });
 3540    }
 3541}
 3542
 3543#[derive(Debug)]
 3544pub struct FormattableBuffer {
 3545    handle: Entity<Buffer>,
 3546    abs_path: Option<PathBuf>,
 3547    env: Option<HashMap<String, String>>,
 3548    ranges: Option<Vec<Range<Anchor>>>,
 3549}
 3550
 3551pub struct RemoteLspStore {
 3552    upstream_client: Option<AnyProtoClient>,
 3553    upstream_project_id: u64,
 3554}
 3555
 3556pub(crate) enum LspStoreMode {
 3557    Local(LocalLspStore),   // ssh host and collab host
 3558    Remote(RemoteLspStore), // collab guest
 3559}
 3560
 3561impl LspStoreMode {
 3562    fn is_local(&self) -> bool {
 3563        matches!(self, LspStoreMode::Local(_))
 3564    }
 3565}
 3566
 3567pub struct LspStore {
 3568    mode: LspStoreMode,
 3569    last_formatting_failure: Option<String>,
 3570    downstream_client: Option<(AnyProtoClient, u64)>,
 3571    nonce: u128,
 3572    buffer_store: Entity<BufferStore>,
 3573    worktree_store: Entity<WorktreeStore>,
 3574    pub languages: Arc<LanguageRegistry>,
 3575    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3576    active_entry: Option<ProjectEntryId>,
 3577    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3578    _maintain_buffer_languages: Task<()>,
 3579    diagnostic_summaries:
 3580        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3581    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3582    lsp_data: HashMap<BufferId, BufferLspData>,
 3583    next_hint_id: Arc<AtomicUsize>,
 3584}
 3585
 3586#[derive(Debug)]
 3587pub struct BufferLspData {
 3588    buffer_version: Global,
 3589    document_colors: Option<DocumentColorData>,
 3590    code_lens: Option<CodeLensData>,
 3591    inlay_hints: BufferInlayHints,
 3592    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3593    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3594}
 3595
 3596#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3597struct LspKey {
 3598    request_type: TypeId,
 3599    server_queried: Option<LanguageServerId>,
 3600}
 3601
 3602impl BufferLspData {
 3603    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3604        Self {
 3605            buffer_version: buffer.read(cx).version(),
 3606            document_colors: None,
 3607            code_lens: None,
 3608            inlay_hints: BufferInlayHints::new(buffer, cx),
 3609            lsp_requests: HashMap::default(),
 3610            chunk_lsp_requests: HashMap::default(),
 3611        }
 3612    }
 3613
 3614    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3615        if let Some(document_colors) = &mut self.document_colors {
 3616            document_colors.colors.remove(&for_server);
 3617            document_colors.cache_version += 1;
 3618        }
 3619
 3620        if let Some(code_lens) = &mut self.code_lens {
 3621            code_lens.lens.remove(&for_server);
 3622        }
 3623
 3624        self.inlay_hints.remove_server_data(for_server);
 3625    }
 3626
 3627    #[cfg(any(test, feature = "test-support"))]
 3628    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3629        &self.inlay_hints
 3630    }
 3631}
 3632
 3633#[derive(Debug, Default, Clone)]
 3634pub struct DocumentColors {
 3635    pub colors: HashSet<DocumentColor>,
 3636    pub cache_version: Option<usize>,
 3637}
 3638
 3639type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3640type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3641
 3642#[derive(Debug, Default)]
 3643struct DocumentColorData {
 3644    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3645    cache_version: usize,
 3646    colors_update: Option<(Global, DocumentColorTask)>,
 3647}
 3648
 3649#[derive(Debug, Default)]
 3650struct CodeLensData {
 3651    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3652    update: Option<(Global, CodeLensTask)>,
 3653}
 3654
 3655#[derive(Debug)]
 3656pub enum LspStoreEvent {
 3657    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3658    LanguageServerRemoved(LanguageServerId),
 3659    LanguageServerUpdate {
 3660        language_server_id: LanguageServerId,
 3661        name: Option<LanguageServerName>,
 3662        message: proto::update_language_server::Variant,
 3663    },
 3664    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3665    LanguageServerPrompt(LanguageServerPromptRequest),
 3666    LanguageDetected {
 3667        buffer: Entity<Buffer>,
 3668        new_language: Option<Arc<Language>>,
 3669    },
 3670    Notification(String),
 3671    RefreshInlayHints {
 3672        server_id: LanguageServerId,
 3673        request_id: Option<usize>,
 3674    },
 3675    RefreshCodeLens,
 3676    DiagnosticsUpdated {
 3677        server_id: LanguageServerId,
 3678        paths: Vec<ProjectPath>,
 3679    },
 3680    DiskBasedDiagnosticsStarted {
 3681        language_server_id: LanguageServerId,
 3682    },
 3683    DiskBasedDiagnosticsFinished {
 3684        language_server_id: LanguageServerId,
 3685    },
 3686    SnippetEdit {
 3687        buffer_id: BufferId,
 3688        edits: Vec<(lsp::Range, Snippet)>,
 3689        most_recent_edit: clock::Lamport,
 3690    },
 3691}
 3692
 3693#[derive(Clone, Debug, Serialize)]
 3694pub struct LanguageServerStatus {
 3695    pub name: LanguageServerName,
 3696    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3697    pub has_pending_diagnostic_updates: bool,
 3698    progress_tokens: HashSet<ProgressToken>,
 3699    pub worktree: Option<WorktreeId>,
 3700}
 3701
 3702#[derive(Clone, Debug)]
 3703struct CoreSymbol {
 3704    pub language_server_name: LanguageServerName,
 3705    pub source_worktree_id: WorktreeId,
 3706    pub source_language_server_id: LanguageServerId,
 3707    pub path: SymbolLocation,
 3708    pub name: String,
 3709    pub kind: lsp::SymbolKind,
 3710    pub range: Range<Unclipped<PointUtf16>>,
 3711}
 3712
 3713#[derive(Clone, Debug, PartialEq, Eq)]
 3714pub enum SymbolLocation {
 3715    InProject(ProjectPath),
 3716    OutsideProject {
 3717        abs_path: Arc<Path>,
 3718        signature: [u8; 32],
 3719    },
 3720}
 3721
 3722impl SymbolLocation {
 3723    fn file_name(&self) -> Option<&str> {
 3724        match self {
 3725            Self::InProject(path) => path.path.file_name(),
 3726            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3727        }
 3728    }
 3729}
 3730
 3731impl LspStore {
 3732    pub fn init(client: &AnyProtoClient) {
 3733        client.add_entity_request_handler(Self::handle_lsp_query);
 3734        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3735        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3736        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3737        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3738        client.add_entity_message_handler(Self::handle_start_language_server);
 3739        client.add_entity_message_handler(Self::handle_update_language_server);
 3740        client.add_entity_message_handler(Self::handle_language_server_log);
 3741        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3742        client.add_entity_request_handler(Self::handle_format_buffers);
 3743        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3744        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3745        client.add_entity_request_handler(Self::handle_apply_code_action);
 3746        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3747        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3748        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3749        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3750        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3751        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3752        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3753        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3754        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3755        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3756        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3757        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3758        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3759        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3760        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3761        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3762        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3763
 3764        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3765        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3766        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3767        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3768        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3769        client.add_entity_request_handler(
 3770            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3771        );
 3772        client.add_entity_request_handler(
 3773            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3774        );
 3775        client.add_entity_request_handler(
 3776            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3777        );
 3778    }
 3779
 3780    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3781        match &self.mode {
 3782            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3783            _ => None,
 3784        }
 3785    }
 3786
 3787    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3788        match &self.mode {
 3789            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3790            _ => None,
 3791        }
 3792    }
 3793
 3794    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3795        match &mut self.mode {
 3796            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3797            _ => None,
 3798        }
 3799    }
 3800
 3801    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3802        match &self.mode {
 3803            LspStoreMode::Remote(RemoteLspStore {
 3804                upstream_client: Some(upstream_client),
 3805                upstream_project_id,
 3806                ..
 3807            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3808
 3809            LspStoreMode::Remote(RemoteLspStore {
 3810                upstream_client: None,
 3811                ..
 3812            }) => None,
 3813            LspStoreMode::Local(_) => None,
 3814        }
 3815    }
 3816
 3817    pub fn new_local(
 3818        buffer_store: Entity<BufferStore>,
 3819        worktree_store: Entity<WorktreeStore>,
 3820        prettier_store: Entity<PrettierStore>,
 3821        toolchain_store: Entity<LocalToolchainStore>,
 3822        environment: Entity<ProjectEnvironment>,
 3823        manifest_tree: Entity<ManifestTree>,
 3824        languages: Arc<LanguageRegistry>,
 3825        http_client: Arc<dyn HttpClient>,
 3826        fs: Arc<dyn Fs>,
 3827        cx: &mut Context<Self>,
 3828    ) -> Self {
 3829        let yarn = YarnPathStore::new(fs.clone(), cx);
 3830        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3831            .detach();
 3832        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3833            .detach();
 3834        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3835            .detach();
 3836        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3837            .detach();
 3838        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3839            .detach();
 3840        subscribe_to_binary_statuses(&languages, cx).detach();
 3841
 3842        let _maintain_workspace_config = {
 3843            let (sender, receiver) = watch::channel();
 3844            (Self::maintain_workspace_config(receiver, cx), sender)
 3845        };
 3846
 3847        Self {
 3848            mode: LspStoreMode::Local(LocalLspStore {
 3849                weak: cx.weak_entity(),
 3850                worktree_store: worktree_store.clone(),
 3851
 3852                supplementary_language_servers: Default::default(),
 3853                languages: languages.clone(),
 3854                language_server_ids: Default::default(),
 3855                language_servers: Default::default(),
 3856                last_workspace_edits_by_language_server: Default::default(),
 3857                language_server_watched_paths: Default::default(),
 3858                language_server_paths_watched_for_rename: Default::default(),
 3859                language_server_dynamic_registrations: Default::default(),
 3860                buffers_being_formatted: Default::default(),
 3861                buffer_snapshots: Default::default(),
 3862                prettier_store,
 3863                environment,
 3864                http_client,
 3865                fs,
 3866                yarn,
 3867                next_diagnostic_group_id: Default::default(),
 3868                diagnostics: Default::default(),
 3869                _subscription: cx.on_app_quit(|this, cx| {
 3870                    this.as_local_mut()
 3871                        .unwrap()
 3872                        .shutdown_language_servers_on_quit(cx)
 3873                }),
 3874                lsp_tree: LanguageServerTree::new(
 3875                    manifest_tree,
 3876                    languages.clone(),
 3877                    toolchain_store.clone(),
 3878                ),
 3879                toolchain_store,
 3880                registered_buffers: HashMap::default(),
 3881                buffers_opened_in_servers: HashMap::default(),
 3882                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3883                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3884                    .manifest_file_names(),
 3885            }),
 3886            last_formatting_failure: None,
 3887            downstream_client: None,
 3888            buffer_store,
 3889            worktree_store,
 3890            languages: languages.clone(),
 3891            language_server_statuses: Default::default(),
 3892            nonce: StdRng::from_os_rng().random(),
 3893            diagnostic_summaries: HashMap::default(),
 3894            lsp_server_capabilities: HashMap::default(),
 3895            lsp_data: HashMap::default(),
 3896            next_hint_id: Arc::default(),
 3897            active_entry: None,
 3898            _maintain_workspace_config,
 3899            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3900        }
 3901    }
 3902
 3903    fn send_lsp_proto_request<R: LspCommand>(
 3904        &self,
 3905        buffer: Entity<Buffer>,
 3906        client: AnyProtoClient,
 3907        upstream_project_id: u64,
 3908        request: R,
 3909        cx: &mut Context<LspStore>,
 3910    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3911        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3912            return Task::ready(Ok(R::Response::default()));
 3913        }
 3914        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3915        cx.spawn(async move |this, cx| {
 3916            let response = client.request(message).await?;
 3917            let this = this.upgrade().context("project dropped")?;
 3918            request
 3919                .response_from_proto(response, this, buffer, cx.clone())
 3920                .await
 3921        })
 3922    }
 3923
 3924    pub(super) fn new_remote(
 3925        buffer_store: Entity<BufferStore>,
 3926        worktree_store: Entity<WorktreeStore>,
 3927        languages: Arc<LanguageRegistry>,
 3928        upstream_client: AnyProtoClient,
 3929        project_id: u64,
 3930        cx: &mut Context<Self>,
 3931    ) -> Self {
 3932        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3933            .detach();
 3934        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3935            .detach();
 3936        subscribe_to_binary_statuses(&languages, cx).detach();
 3937        let _maintain_workspace_config = {
 3938            let (sender, receiver) = watch::channel();
 3939            (Self::maintain_workspace_config(receiver, cx), sender)
 3940        };
 3941        Self {
 3942            mode: LspStoreMode::Remote(RemoteLspStore {
 3943                upstream_client: Some(upstream_client),
 3944                upstream_project_id: project_id,
 3945            }),
 3946            downstream_client: None,
 3947            last_formatting_failure: None,
 3948            buffer_store,
 3949            worktree_store,
 3950            languages: languages.clone(),
 3951            language_server_statuses: Default::default(),
 3952            nonce: StdRng::from_os_rng().random(),
 3953            diagnostic_summaries: HashMap::default(),
 3954            lsp_server_capabilities: HashMap::default(),
 3955            next_hint_id: Arc::default(),
 3956            lsp_data: HashMap::default(),
 3957            active_entry: None,
 3958
 3959            _maintain_workspace_config,
 3960            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3961        }
 3962    }
 3963
 3964    fn on_buffer_store_event(
 3965        &mut self,
 3966        _: Entity<BufferStore>,
 3967        event: &BufferStoreEvent,
 3968        cx: &mut Context<Self>,
 3969    ) {
 3970        match event {
 3971            BufferStoreEvent::BufferAdded(buffer) => {
 3972                self.on_buffer_added(buffer, cx).log_err();
 3973            }
 3974            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3975                let buffer_id = buffer.read(cx).remote_id();
 3976                if let Some(local) = self.as_local_mut()
 3977                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3978                {
 3979                    local.reset_buffer(buffer, old_file, cx);
 3980
 3981                    if local.registered_buffers.contains_key(&buffer_id) {
 3982                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3983                    }
 3984                }
 3985
 3986                self.detect_language_for_buffer(buffer, cx);
 3987                if let Some(local) = self.as_local_mut() {
 3988                    local.initialize_buffer(buffer, cx);
 3989                    if local.registered_buffers.contains_key(&buffer_id) {
 3990                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3991                    }
 3992                }
 3993            }
 3994            _ => {}
 3995        }
 3996    }
 3997
 3998    fn on_worktree_store_event(
 3999        &mut self,
 4000        _: Entity<WorktreeStore>,
 4001        event: &WorktreeStoreEvent,
 4002        cx: &mut Context<Self>,
 4003    ) {
 4004        match event {
 4005            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4006                if !worktree.read(cx).is_local() {
 4007                    return;
 4008                }
 4009                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4010                    worktree::Event::UpdatedEntries(changes) => {
 4011                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4012                    }
 4013                    worktree::Event::UpdatedGitRepositories(_)
 4014                    | worktree::Event::DeletedEntry(_) => {}
 4015                })
 4016                .detach()
 4017            }
 4018            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4019            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4020                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4021            }
 4022            WorktreeStoreEvent::WorktreeReleased(..)
 4023            | WorktreeStoreEvent::WorktreeOrderChanged
 4024            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4025            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4026            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4027        }
 4028    }
 4029
 4030    fn on_prettier_store_event(
 4031        &mut self,
 4032        _: Entity<PrettierStore>,
 4033        event: &PrettierStoreEvent,
 4034        cx: &mut Context<Self>,
 4035    ) {
 4036        match event {
 4037            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4038                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4039            }
 4040            PrettierStoreEvent::LanguageServerAdded {
 4041                new_server_id,
 4042                name,
 4043                prettier_server,
 4044            } => {
 4045                self.register_supplementary_language_server(
 4046                    *new_server_id,
 4047                    name.clone(),
 4048                    prettier_server.clone(),
 4049                    cx,
 4050                );
 4051            }
 4052        }
 4053    }
 4054
 4055    fn on_toolchain_store_event(
 4056        &mut self,
 4057        _: Entity<LocalToolchainStore>,
 4058        event: &ToolchainStoreEvent,
 4059        _: &mut Context<Self>,
 4060    ) {
 4061        if let ToolchainStoreEvent::ToolchainActivated = event {
 4062            self.request_workspace_config_refresh()
 4063        }
 4064    }
 4065
 4066    fn request_workspace_config_refresh(&mut self) {
 4067        *self._maintain_workspace_config.1.borrow_mut() = ();
 4068    }
 4069
 4070    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4071        self.as_local().map(|local| local.prettier_store.clone())
 4072    }
 4073
 4074    fn on_buffer_event(
 4075        &mut self,
 4076        buffer: Entity<Buffer>,
 4077        event: &language::BufferEvent,
 4078        cx: &mut Context<Self>,
 4079    ) {
 4080        match event {
 4081            language::BufferEvent::Edited => {
 4082                self.on_buffer_edited(buffer, cx);
 4083            }
 4084
 4085            language::BufferEvent::Saved => {
 4086                self.on_buffer_saved(buffer, cx);
 4087            }
 4088
 4089            _ => {}
 4090        }
 4091    }
 4092
 4093    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4094        buffer
 4095            .read(cx)
 4096            .set_language_registry(self.languages.clone());
 4097
 4098        cx.subscribe(buffer, |this, buffer, event, cx| {
 4099            this.on_buffer_event(buffer, event, cx);
 4100        })
 4101        .detach();
 4102
 4103        self.detect_language_for_buffer(buffer, cx);
 4104        if let Some(local) = self.as_local_mut() {
 4105            local.initialize_buffer(buffer, cx);
 4106        }
 4107
 4108        Ok(())
 4109    }
 4110
 4111    pub(crate) fn register_buffer_with_language_servers(
 4112        &mut self,
 4113        buffer: &Entity<Buffer>,
 4114        only_register_servers: HashSet<LanguageServerSelector>,
 4115        ignore_refcounts: bool,
 4116        cx: &mut Context<Self>,
 4117    ) -> OpenLspBufferHandle {
 4118        let buffer_id = buffer.read(cx).remote_id();
 4119        let handle = cx.new(|_| buffer.clone());
 4120        if let Some(local) = self.as_local_mut() {
 4121            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4122            if !ignore_refcounts {
 4123                *refcount += 1;
 4124            }
 4125
 4126            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4127            // When a new unnamed buffer is created and saved, we will start loading it's language. Once the language is loaded, we go over all "language-less" buffers and try to fit that new language
 4128            // with them. However, we do that only for the buffers that we think are open in at least one editor; thus, we need to keep tab of unnamed buffers as well, even though they're not actually registered with any language
 4129            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4130            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4131                return handle;
 4132            };
 4133            if !file.is_local() {
 4134                return handle;
 4135            }
 4136
 4137            if ignore_refcounts || *refcount == 1 {
 4138                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4139            }
 4140            if !ignore_refcounts {
 4141                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4142                    let refcount = {
 4143                        let local = lsp_store.as_local_mut().unwrap();
 4144                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4145                            debug_panic!("bad refcounting");
 4146                            return;
 4147                        };
 4148
 4149                        *refcount -= 1;
 4150                        *refcount
 4151                    };
 4152                    if refcount == 0 {
 4153                        lsp_store.lsp_data.remove(&buffer_id);
 4154                        let local = lsp_store.as_local_mut().unwrap();
 4155                        local.registered_buffers.remove(&buffer_id);
 4156                        local.buffers_opened_in_servers.remove(&buffer_id);
 4157                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4158                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4159                        }
 4160                    }
 4161                })
 4162                .detach();
 4163            }
 4164        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4165            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4166            cx.background_spawn(async move {
 4167                upstream_client
 4168                    .request(proto::RegisterBufferWithLanguageServers {
 4169                        project_id: upstream_project_id,
 4170                        buffer_id,
 4171                        only_servers: only_register_servers
 4172                            .into_iter()
 4173                            .map(|selector| {
 4174                                let selector = match selector {
 4175                                    LanguageServerSelector::Id(language_server_id) => {
 4176                                        proto::language_server_selector::Selector::ServerId(
 4177                                            language_server_id.to_proto(),
 4178                                        )
 4179                                    }
 4180                                    LanguageServerSelector::Name(language_server_name) => {
 4181                                        proto::language_server_selector::Selector::Name(
 4182                                            language_server_name.to_string(),
 4183                                        )
 4184                                    }
 4185                                };
 4186                                proto::LanguageServerSelector {
 4187                                    selector: Some(selector),
 4188                                }
 4189                            })
 4190                            .collect(),
 4191                    })
 4192                    .await
 4193            })
 4194            .detach();
 4195        } else {
 4196            // Our remote connection got closed
 4197        }
 4198        handle
 4199    }
 4200
 4201    fn maintain_buffer_languages(
 4202        languages: Arc<LanguageRegistry>,
 4203        cx: &mut Context<Self>,
 4204    ) -> Task<()> {
 4205        let mut subscription = languages.subscribe();
 4206        let mut prev_reload_count = languages.reload_count();
 4207        cx.spawn(async move |this, cx| {
 4208            while let Some(()) = subscription.next().await {
 4209                if let Some(this) = this.upgrade() {
 4210                    // If the language registry has been reloaded, then remove and
 4211                    // re-assign the languages on all open buffers.
 4212                    let reload_count = languages.reload_count();
 4213                    if reload_count > prev_reload_count {
 4214                        prev_reload_count = reload_count;
 4215                        this.update(cx, |this, cx| {
 4216                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4217                                for buffer in buffer_store.buffers() {
 4218                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4219                                    {
 4220                                        buffer
 4221                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4222                                        if let Some(local) = this.as_local_mut() {
 4223                                            local.reset_buffer(&buffer, &f, cx);
 4224
 4225                                            if local
 4226                                                .registered_buffers
 4227                                                .contains_key(&buffer.read(cx).remote_id())
 4228                                                && let Some(file_url) =
 4229                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4230                                            {
 4231                                                local.unregister_buffer_from_language_servers(
 4232                                                    &buffer, &file_url, cx,
 4233                                                );
 4234                                            }
 4235                                        }
 4236                                    }
 4237                                }
 4238                            });
 4239                        })
 4240                        .ok();
 4241                    }
 4242
 4243                    this.update(cx, |this, cx| {
 4244                        let mut plain_text_buffers = Vec::new();
 4245                        let mut buffers_with_unknown_injections = Vec::new();
 4246                        for handle in this.buffer_store.read(cx).buffers() {
 4247                            let buffer = handle.read(cx);
 4248                            if buffer.language().is_none()
 4249                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4250                            {
 4251                                plain_text_buffers.push(handle);
 4252                            } else if buffer.contains_unknown_injections() {
 4253                                buffers_with_unknown_injections.push(handle);
 4254                            }
 4255                        }
 4256
 4257                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4258                        // and reused later in the invisible worktrees.
 4259                        plain_text_buffers.sort_by_key(|buffer| {
 4260                            Reverse(
 4261                                File::from_dyn(buffer.read(cx).file())
 4262                                    .map(|file| file.worktree.read(cx).is_visible()),
 4263                            )
 4264                        });
 4265
 4266                        for buffer in plain_text_buffers {
 4267                            this.detect_language_for_buffer(&buffer, cx);
 4268                            if let Some(local) = this.as_local_mut() {
 4269                                local.initialize_buffer(&buffer, cx);
 4270                                if local
 4271                                    .registered_buffers
 4272                                    .contains_key(&buffer.read(cx).remote_id())
 4273                                {
 4274                                    local.register_buffer_with_language_servers(
 4275                                        &buffer,
 4276                                        HashSet::default(),
 4277                                        cx,
 4278                                    );
 4279                                }
 4280                            }
 4281                        }
 4282
 4283                        for buffer in buffers_with_unknown_injections {
 4284                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4285                        }
 4286                    })
 4287                    .ok();
 4288                }
 4289            }
 4290        })
 4291    }
 4292
 4293    fn detect_language_for_buffer(
 4294        &mut self,
 4295        buffer_handle: &Entity<Buffer>,
 4296        cx: &mut Context<Self>,
 4297    ) -> Option<language::AvailableLanguage> {
 4298        // If the buffer has a language, set it and start the language server if we haven't already.
 4299        let buffer = buffer_handle.read(cx);
 4300        let file = buffer.file()?;
 4301
 4302        let content = buffer.as_rope();
 4303        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4304        if let Some(available_language) = &available_language {
 4305            if let Some(Ok(Ok(new_language))) = self
 4306                .languages
 4307                .load_language(available_language)
 4308                .now_or_never()
 4309            {
 4310                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4311            }
 4312        } else {
 4313            cx.emit(LspStoreEvent::LanguageDetected {
 4314                buffer: buffer_handle.clone(),
 4315                new_language: None,
 4316            });
 4317        }
 4318
 4319        available_language
 4320    }
 4321
 4322    pub(crate) fn set_language_for_buffer(
 4323        &mut self,
 4324        buffer_entity: &Entity<Buffer>,
 4325        new_language: Arc<Language>,
 4326        cx: &mut Context<Self>,
 4327    ) {
 4328        let buffer = buffer_entity.read(cx);
 4329        let buffer_file = buffer.file().cloned();
 4330        let buffer_id = buffer.remote_id();
 4331        if let Some(local_store) = self.as_local_mut()
 4332            && local_store.registered_buffers.contains_key(&buffer_id)
 4333            && let Some(abs_path) =
 4334                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4335            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4336        {
 4337            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4338        }
 4339        buffer_entity.update(cx, |buffer, cx| {
 4340            if buffer
 4341                .language()
 4342                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4343            {
 4344                buffer.set_language(Some(new_language.clone()), cx);
 4345            }
 4346        });
 4347
 4348        let settings =
 4349            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4350        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4351
 4352        let worktree_id = if let Some(file) = buffer_file {
 4353            let worktree = file.worktree.clone();
 4354
 4355            if let Some(local) = self.as_local_mut()
 4356                && local.registered_buffers.contains_key(&buffer_id)
 4357            {
 4358                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4359            }
 4360            Some(worktree.read(cx).id())
 4361        } else {
 4362            None
 4363        };
 4364
 4365        if settings.prettier.allowed
 4366            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4367        {
 4368            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4369            if let Some(prettier_store) = prettier_store {
 4370                prettier_store.update(cx, |prettier_store, cx| {
 4371                    prettier_store.install_default_prettier(
 4372                        worktree_id,
 4373                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4374                        cx,
 4375                    )
 4376                })
 4377            }
 4378        }
 4379
 4380        cx.emit(LspStoreEvent::LanguageDetected {
 4381            buffer: buffer_entity.clone(),
 4382            new_language: Some(new_language),
 4383        })
 4384    }
 4385
 4386    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4387        self.buffer_store.clone()
 4388    }
 4389
 4390    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4391        self.active_entry = active_entry;
 4392    }
 4393
 4394    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4395        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4396            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4397        {
 4398            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4399                summaries
 4400                    .iter()
 4401                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4402            });
 4403            if let Some(summary) = summaries.next() {
 4404                client
 4405                    .send(proto::UpdateDiagnosticSummary {
 4406                        project_id: downstream_project_id,
 4407                        worktree_id: worktree.id().to_proto(),
 4408                        summary: Some(summary),
 4409                        more_summaries: summaries.collect(),
 4410                    })
 4411                    .log_err();
 4412            }
 4413        }
 4414    }
 4415
 4416    fn is_capable_for_proto_request<R>(
 4417        &self,
 4418        buffer: &Entity<Buffer>,
 4419        request: &R,
 4420        cx: &App,
 4421    ) -> bool
 4422    where
 4423        R: LspCommand,
 4424    {
 4425        self.check_if_capable_for_proto_request(
 4426            buffer,
 4427            |capabilities| {
 4428                request.check_capabilities(AdapterServerCapabilities {
 4429                    server_capabilities: capabilities.clone(),
 4430                    code_action_kinds: None,
 4431                })
 4432            },
 4433            cx,
 4434        )
 4435    }
 4436
 4437    fn check_if_capable_for_proto_request<F>(
 4438        &self,
 4439        buffer: &Entity<Buffer>,
 4440        check: F,
 4441        cx: &App,
 4442    ) -> bool
 4443    where
 4444        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4445    {
 4446        let Some(language) = buffer.read(cx).language().cloned() else {
 4447            return false;
 4448        };
 4449        let relevant_language_servers = self
 4450            .languages
 4451            .lsp_adapters(&language.name())
 4452            .into_iter()
 4453            .map(|lsp_adapter| lsp_adapter.name())
 4454            .collect::<HashSet<_>>();
 4455        self.language_server_statuses
 4456            .iter()
 4457            .filter_map(|(server_id, server_status)| {
 4458                relevant_language_servers
 4459                    .contains(&server_status.name)
 4460                    .then_some(server_id)
 4461            })
 4462            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4463            .any(check)
 4464    }
 4465
 4466    pub fn request_lsp<R>(
 4467        &mut self,
 4468        buffer: Entity<Buffer>,
 4469        server: LanguageServerToQuery,
 4470        request: R,
 4471        cx: &mut Context<Self>,
 4472    ) -> Task<Result<R::Response>>
 4473    where
 4474        R: LspCommand,
 4475        <R::LspRequest as lsp::request::Request>::Result: Send,
 4476        <R::LspRequest as lsp::request::Request>::Params: Send,
 4477    {
 4478        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4479            return self.send_lsp_proto_request(
 4480                buffer,
 4481                upstream_client,
 4482                upstream_project_id,
 4483                request,
 4484                cx,
 4485            );
 4486        }
 4487
 4488        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4489            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4490                local
 4491                    .language_servers_for_buffer(buffer, cx)
 4492                    .find(|(_, server)| {
 4493                        request.check_capabilities(server.adapter_server_capabilities())
 4494                    })
 4495                    .map(|(_, server)| server.clone())
 4496            }),
 4497            LanguageServerToQuery::Other(id) => self
 4498                .language_server_for_local_buffer(buffer, id, cx)
 4499                .and_then(|(_, server)| {
 4500                    request
 4501                        .check_capabilities(server.adapter_server_capabilities())
 4502                        .then(|| Arc::clone(server))
 4503                }),
 4504        }) else {
 4505            return Task::ready(Ok(Default::default()));
 4506        };
 4507
 4508        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4509
 4510        let Some(file) = file else {
 4511            return Task::ready(Ok(Default::default()));
 4512        };
 4513
 4514        let lsp_params = match request.to_lsp_params_or_response(
 4515            &file.abs_path(cx),
 4516            buffer.read(cx),
 4517            &language_server,
 4518            cx,
 4519        ) {
 4520            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4521            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4522            Err(err) => {
 4523                let message = format!(
 4524                    "{} via {} failed: {}",
 4525                    request.display_name(),
 4526                    language_server.name(),
 4527                    err
 4528                );
 4529                // rust-analyzer likes to error with this when its still loading up
 4530                if !message.ends_with("content modified") {
 4531                    log::warn!("{message}");
 4532                }
 4533                return Task::ready(Err(anyhow!(message)));
 4534            }
 4535        };
 4536
 4537        let status = request.status();
 4538        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4539            return Task::ready(Ok(Default::default()));
 4540        }
 4541        cx.spawn(async move |this, cx| {
 4542            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4543
 4544            let id = lsp_request.id();
 4545            let _cleanup = if status.is_some() {
 4546                cx.update(|cx| {
 4547                    this.update(cx, |this, cx| {
 4548                        this.on_lsp_work_start(
 4549                            language_server.server_id(),
 4550                            ProgressToken::Number(id),
 4551                            LanguageServerProgress {
 4552                                is_disk_based_diagnostics_progress: false,
 4553                                is_cancellable: false,
 4554                                title: None,
 4555                                message: status.clone(),
 4556                                percentage: None,
 4557                                last_update_at: cx.background_executor().now(),
 4558                            },
 4559                            cx,
 4560                        );
 4561                    })
 4562                })
 4563                .log_err();
 4564
 4565                Some(defer(|| {
 4566                    cx.update(|cx| {
 4567                        this.update(cx, |this, cx| {
 4568                            this.on_lsp_work_end(
 4569                                language_server.server_id(),
 4570                                ProgressToken::Number(id),
 4571                                cx,
 4572                            );
 4573                        })
 4574                    })
 4575                    .log_err();
 4576                }))
 4577            } else {
 4578                None
 4579            };
 4580
 4581            let result = lsp_request.await.into_response();
 4582
 4583            let response = result.map_err(|err| {
 4584                let message = format!(
 4585                    "{} via {} failed: {}",
 4586                    request.display_name(),
 4587                    language_server.name(),
 4588                    err
 4589                );
 4590                // rust-analyzer likes to error with this when its still loading up
 4591                if !message.ends_with("content modified") {
 4592                    log::warn!("{message}");
 4593                }
 4594                anyhow::anyhow!(message)
 4595            })?;
 4596
 4597            request
 4598                .response_from_lsp(
 4599                    response,
 4600                    this.upgrade().context("no app context")?,
 4601                    buffer,
 4602                    language_server.server_id(),
 4603                    cx.clone(),
 4604                )
 4605                .await
 4606        })
 4607    }
 4608
 4609    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4610        let mut language_formatters_to_check = Vec::new();
 4611        for buffer in self.buffer_store.read(cx).buffers() {
 4612            let buffer = buffer.read(cx);
 4613            let buffer_file = File::from_dyn(buffer.file());
 4614            let buffer_language = buffer.language();
 4615            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4616            if buffer_language.is_some() {
 4617                language_formatters_to_check.push((
 4618                    buffer_file.map(|f| f.worktree_id(cx)),
 4619                    settings.into_owned(),
 4620                ));
 4621            }
 4622        }
 4623
 4624        self.request_workspace_config_refresh();
 4625
 4626        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4627            prettier_store.update(cx, |prettier_store, cx| {
 4628                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4629            })
 4630        }
 4631
 4632        cx.notify();
 4633    }
 4634
 4635    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4636        let buffer_store = self.buffer_store.clone();
 4637        let Some(local) = self.as_local_mut() else {
 4638            return;
 4639        };
 4640        let mut adapters = BTreeMap::default();
 4641        let get_adapter = {
 4642            let languages = local.languages.clone();
 4643            let environment = local.environment.clone();
 4644            let weak = local.weak.clone();
 4645            let worktree_store = local.worktree_store.clone();
 4646            let http_client = local.http_client.clone();
 4647            let fs = local.fs.clone();
 4648            move |worktree_id, cx: &mut App| {
 4649                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4650                Some(LocalLspAdapterDelegate::new(
 4651                    languages.clone(),
 4652                    &environment,
 4653                    weak.clone(),
 4654                    &worktree,
 4655                    http_client.clone(),
 4656                    fs.clone(),
 4657                    cx,
 4658                ))
 4659            }
 4660        };
 4661
 4662        let mut messages_to_report = Vec::new();
 4663        let (new_tree, to_stop) = {
 4664            let mut rebase = local.lsp_tree.rebase();
 4665            let buffers = buffer_store
 4666                .read(cx)
 4667                .buffers()
 4668                .filter_map(|buffer| {
 4669                    let raw_buffer = buffer.read(cx);
 4670                    if !local
 4671                        .registered_buffers
 4672                        .contains_key(&raw_buffer.remote_id())
 4673                    {
 4674                        return None;
 4675                    }
 4676                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4677                    let language = raw_buffer.language().cloned()?;
 4678                    Some((file, language, raw_buffer.remote_id()))
 4679                })
 4680                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4681            for (file, language, buffer_id) in buffers {
 4682                let worktree_id = file.worktree_id(cx);
 4683                let Some(worktree) = local
 4684                    .worktree_store
 4685                    .read(cx)
 4686                    .worktree_for_id(worktree_id, cx)
 4687                else {
 4688                    continue;
 4689                };
 4690
 4691                if let Some((_, apply)) = local.reuse_existing_language_server(
 4692                    rebase.server_tree(),
 4693                    &worktree,
 4694                    &language.name(),
 4695                    cx,
 4696                ) {
 4697                    (apply)(rebase.server_tree());
 4698                } else if let Some(lsp_delegate) = adapters
 4699                    .entry(worktree_id)
 4700                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4701                    .clone()
 4702                {
 4703                    let delegate =
 4704                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4705                    let path = file
 4706                        .path()
 4707                        .parent()
 4708                        .map(Arc::from)
 4709                        .unwrap_or_else(|| file.path().clone());
 4710                    let worktree_path = ProjectPath { worktree_id, path };
 4711                    let abs_path = file.abs_path(cx);
 4712                    let nodes = rebase
 4713                        .walk(
 4714                            worktree_path,
 4715                            language.name(),
 4716                            language.manifest(),
 4717                            delegate.clone(),
 4718                            cx,
 4719                        )
 4720                        .collect::<Vec<_>>();
 4721                    for node in nodes {
 4722                        let server_id = node.server_id_or_init(|disposition| {
 4723                            let path = &disposition.path;
 4724                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4725                            let key = LanguageServerSeed {
 4726                                worktree_id,
 4727                                name: disposition.server_name.clone(),
 4728                                settings: disposition.settings.clone(),
 4729                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4730                                    path.worktree_id,
 4731                                    &path.path,
 4732                                    language.name(),
 4733                                ),
 4734                            };
 4735                            local.language_server_ids.remove(&key);
 4736
 4737                            let server_id = local.get_or_insert_language_server(
 4738                                &worktree,
 4739                                lsp_delegate.clone(),
 4740                                disposition,
 4741                                &language.name(),
 4742                                cx,
 4743                            );
 4744                            if let Some(state) = local.language_servers.get(&server_id)
 4745                                && let Ok(uri) = uri
 4746                            {
 4747                                state.add_workspace_folder(uri);
 4748                            };
 4749                            server_id
 4750                        });
 4751
 4752                        if let Some(language_server_id) = server_id {
 4753                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4754                                language_server_id,
 4755                                name: node.name(),
 4756                                message:
 4757                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4758                                        proto::RegisteredForBuffer {
 4759                                            buffer_abs_path: abs_path
 4760                                                .to_string_lossy()
 4761                                                .into_owned(),
 4762                                            buffer_id: buffer_id.to_proto(),
 4763                                        },
 4764                                    ),
 4765                            });
 4766                        }
 4767                    }
 4768                } else {
 4769                    continue;
 4770                }
 4771            }
 4772            rebase.finish()
 4773        };
 4774        for message in messages_to_report {
 4775            cx.emit(message);
 4776        }
 4777        local.lsp_tree = new_tree;
 4778        for (id, _) in to_stop {
 4779            self.stop_local_language_server(id, cx).detach();
 4780        }
 4781    }
 4782
 4783    pub fn apply_code_action(
 4784        &self,
 4785        buffer_handle: Entity<Buffer>,
 4786        mut action: CodeAction,
 4787        push_to_history: bool,
 4788        cx: &mut Context<Self>,
 4789    ) -> Task<Result<ProjectTransaction>> {
 4790        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4791            let request = proto::ApplyCodeAction {
 4792                project_id,
 4793                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4794                action: Some(Self::serialize_code_action(&action)),
 4795            };
 4796            let buffer_store = self.buffer_store();
 4797            cx.spawn(async move |_, cx| {
 4798                let response = upstream_client
 4799                    .request(request)
 4800                    .await?
 4801                    .transaction
 4802                    .context("missing transaction")?;
 4803
 4804                buffer_store
 4805                    .update(cx, |buffer_store, cx| {
 4806                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4807                    })?
 4808                    .await
 4809            })
 4810        } else if self.mode.is_local() {
 4811            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4812                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4813                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4814            }) else {
 4815                return Task::ready(Ok(ProjectTransaction::default()));
 4816            };
 4817            cx.spawn(async move |this,  cx| {
 4818                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4819                    .await
 4820                    .context("resolving a code action")?;
 4821                if let Some(edit) = action.lsp_action.edit()
 4822                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4823                        return LocalLspStore::deserialize_workspace_edit(
 4824                            this.upgrade().context("no app present")?,
 4825                            edit.clone(),
 4826                            push_to_history,
 4827
 4828                            lang_server.clone(),
 4829                            cx,
 4830                        )
 4831                        .await;
 4832                    }
 4833
 4834                if let Some(command) = action.lsp_action.command() {
 4835                    let server_capabilities = lang_server.capabilities();
 4836                    let available_commands = server_capabilities
 4837                        .execute_command_provider
 4838                        .as_ref()
 4839                        .map(|options| options.commands.as_slice())
 4840                        .unwrap_or_default();
 4841                    if available_commands.contains(&command.command) {
 4842                        this.update(cx, |this, _| {
 4843                            this.as_local_mut()
 4844                                .unwrap()
 4845                                .last_workspace_edits_by_language_server
 4846                                .remove(&lang_server.server_id());
 4847                        })?;
 4848
 4849                        let _result = lang_server
 4850                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4851                                command: command.command.clone(),
 4852                                arguments: command.arguments.clone().unwrap_or_default(),
 4853                                ..lsp::ExecuteCommandParams::default()
 4854                            })
 4855                            .await.into_response()
 4856                            .context("execute command")?;
 4857
 4858                        return this.update(cx, |this, _| {
 4859                            this.as_local_mut()
 4860                                .unwrap()
 4861                                .last_workspace_edits_by_language_server
 4862                                .remove(&lang_server.server_id())
 4863                                .unwrap_or_default()
 4864                        });
 4865                    } else {
 4866                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4867                    }
 4868                }
 4869
 4870                Ok(ProjectTransaction::default())
 4871            })
 4872        } else {
 4873            Task::ready(Err(anyhow!("no upstream client and not local")))
 4874        }
 4875    }
 4876
 4877    pub fn apply_code_action_kind(
 4878        &mut self,
 4879        buffers: HashSet<Entity<Buffer>>,
 4880        kind: CodeActionKind,
 4881        push_to_history: bool,
 4882        cx: &mut Context<Self>,
 4883    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4884        if self.as_local().is_some() {
 4885            cx.spawn(async move |lsp_store, cx| {
 4886                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4887                let result = LocalLspStore::execute_code_action_kind_locally(
 4888                    lsp_store.clone(),
 4889                    buffers,
 4890                    kind,
 4891                    push_to_history,
 4892                    cx,
 4893                )
 4894                .await;
 4895                lsp_store.update(cx, |lsp_store, _| {
 4896                    lsp_store.update_last_formatting_failure(&result);
 4897                })?;
 4898                result
 4899            })
 4900        } else if let Some((client, project_id)) = self.upstream_client() {
 4901            let buffer_store = self.buffer_store();
 4902            cx.spawn(async move |lsp_store, cx| {
 4903                let result = client
 4904                    .request(proto::ApplyCodeActionKind {
 4905                        project_id,
 4906                        kind: kind.as_str().to_owned(),
 4907                        buffer_ids: buffers
 4908                            .iter()
 4909                            .map(|buffer| {
 4910                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4911                            })
 4912                            .collect::<Result<_>>()?,
 4913                    })
 4914                    .await
 4915                    .and_then(|result| result.transaction.context("missing transaction"));
 4916                lsp_store.update(cx, |lsp_store, _| {
 4917                    lsp_store.update_last_formatting_failure(&result);
 4918                })?;
 4919
 4920                let transaction_response = result?;
 4921                buffer_store
 4922                    .update(cx, |buffer_store, cx| {
 4923                        buffer_store.deserialize_project_transaction(
 4924                            transaction_response,
 4925                            push_to_history,
 4926                            cx,
 4927                        )
 4928                    })?
 4929                    .await
 4930            })
 4931        } else {
 4932            Task::ready(Ok(ProjectTransaction::default()))
 4933        }
 4934    }
 4935
 4936    pub fn resolved_hint(
 4937        &mut self,
 4938        buffer_id: BufferId,
 4939        id: InlayId,
 4940        cx: &mut Context<Self>,
 4941    ) -> Option<ResolvedHint> {
 4942        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4943
 4944        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4945        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4946        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4947        let (server_id, resolve_data) = match &hint.resolve_state {
 4948            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4949            ResolveState::Resolving => {
 4950                return Some(ResolvedHint::Resolving(
 4951                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4952                ));
 4953            }
 4954            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4955        };
 4956
 4957        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4958        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4959        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4960            id,
 4961            cx.spawn(async move |lsp_store, cx| {
 4962                let resolved_hint = resolve_task.await;
 4963                lsp_store
 4964                    .update(cx, |lsp_store, _| {
 4965                        if let Some(old_inlay_hint) = lsp_store
 4966                            .lsp_data
 4967                            .get_mut(&buffer_id)
 4968                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4969                        {
 4970                            match resolved_hint {
 4971                                Ok(resolved_hint) => {
 4972                                    *old_inlay_hint = resolved_hint;
 4973                                }
 4974                                Err(e) => {
 4975                                    old_inlay_hint.resolve_state =
 4976                                        ResolveState::CanResolve(server_id, resolve_data);
 4977                                    log::error!("Inlay hint resolve failed: {e:#}");
 4978                                }
 4979                            }
 4980                        }
 4981                    })
 4982                    .ok();
 4983            })
 4984            .shared(),
 4985        );
 4986        debug_assert!(
 4987            previous_task.is_none(),
 4988            "Did not change hint's resolve state after spawning its resolve"
 4989        );
 4990        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4991        None
 4992    }
 4993
 4994    fn resolve_inlay_hint(
 4995        &self,
 4996        mut hint: InlayHint,
 4997        buffer: Entity<Buffer>,
 4998        server_id: LanguageServerId,
 4999        cx: &mut Context<Self>,
 5000    ) -> Task<anyhow::Result<InlayHint>> {
 5001        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5002            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5003            {
 5004                hint.resolve_state = ResolveState::Resolved;
 5005                return Task::ready(Ok(hint));
 5006            }
 5007            let request = proto::ResolveInlayHint {
 5008                project_id,
 5009                buffer_id: buffer.read(cx).remote_id().into(),
 5010                language_server_id: server_id.0 as u64,
 5011                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5012            };
 5013            cx.background_spawn(async move {
 5014                let response = upstream_client
 5015                    .request(request)
 5016                    .await
 5017                    .context("inlay hints proto request")?;
 5018                match response.hint {
 5019                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5020                        .context("inlay hints proto resolve response conversion"),
 5021                    None => Ok(hint),
 5022                }
 5023            })
 5024        } else {
 5025            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5026                self.language_server_for_local_buffer(buffer, server_id, cx)
 5027                    .map(|(_, server)| server.clone())
 5028            }) else {
 5029                return Task::ready(Ok(hint));
 5030            };
 5031            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5032                return Task::ready(Ok(hint));
 5033            }
 5034            let buffer_snapshot = buffer.read(cx).snapshot();
 5035            cx.spawn(async move |_, cx| {
 5036                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5037                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5038                );
 5039                let resolved_hint = resolve_task
 5040                    .await
 5041                    .into_response()
 5042                    .context("inlay hint resolve LSP request")?;
 5043                let resolved_hint = InlayHints::lsp_to_project_hint(
 5044                    resolved_hint,
 5045                    &buffer,
 5046                    server_id,
 5047                    ResolveState::Resolved,
 5048                    false,
 5049                    cx,
 5050                )
 5051                .await?;
 5052                Ok(resolved_hint)
 5053            })
 5054        }
 5055    }
 5056
 5057    pub fn resolve_color_presentation(
 5058        &mut self,
 5059        mut color: DocumentColor,
 5060        buffer: Entity<Buffer>,
 5061        server_id: LanguageServerId,
 5062        cx: &mut Context<Self>,
 5063    ) -> Task<Result<DocumentColor>> {
 5064        if color.resolved {
 5065            return Task::ready(Ok(color));
 5066        }
 5067
 5068        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5069            let start = color.lsp_range.start;
 5070            let end = color.lsp_range.end;
 5071            let request = proto::GetColorPresentation {
 5072                project_id,
 5073                server_id: server_id.to_proto(),
 5074                buffer_id: buffer.read(cx).remote_id().into(),
 5075                color: Some(proto::ColorInformation {
 5076                    red: color.color.red,
 5077                    green: color.color.green,
 5078                    blue: color.color.blue,
 5079                    alpha: color.color.alpha,
 5080                    lsp_range_start: Some(proto::PointUtf16 {
 5081                        row: start.line,
 5082                        column: start.character,
 5083                    }),
 5084                    lsp_range_end: Some(proto::PointUtf16 {
 5085                        row: end.line,
 5086                        column: end.character,
 5087                    }),
 5088                }),
 5089            };
 5090            cx.background_spawn(async move {
 5091                let response = upstream_client
 5092                    .request(request)
 5093                    .await
 5094                    .context("color presentation proto request")?;
 5095                color.resolved = true;
 5096                color.color_presentations = response
 5097                    .presentations
 5098                    .into_iter()
 5099                    .map(|presentation| ColorPresentation {
 5100                        label: SharedString::from(presentation.label),
 5101                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5102                        additional_text_edits: presentation
 5103                            .additional_text_edits
 5104                            .into_iter()
 5105                            .filter_map(deserialize_lsp_edit)
 5106                            .collect(),
 5107                    })
 5108                    .collect();
 5109                Ok(color)
 5110            })
 5111        } else {
 5112            let path = match buffer
 5113                .update(cx, |buffer, cx| {
 5114                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5115                })
 5116                .context("buffer with the missing path")
 5117            {
 5118                Ok(path) => path,
 5119                Err(e) => return Task::ready(Err(e)),
 5120            };
 5121            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5122                self.language_server_for_local_buffer(buffer, server_id, cx)
 5123                    .map(|(_, server)| server.clone())
 5124            }) else {
 5125                return Task::ready(Ok(color));
 5126            };
 5127            cx.background_spawn(async move {
 5128                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5129                    lsp::ColorPresentationParams {
 5130                        text_document: make_text_document_identifier(&path)?,
 5131                        color: color.color,
 5132                        range: color.lsp_range,
 5133                        work_done_progress_params: Default::default(),
 5134                        partial_result_params: Default::default(),
 5135                    },
 5136                );
 5137                color.color_presentations = resolve_task
 5138                    .await
 5139                    .into_response()
 5140                    .context("color presentation resolve LSP request")?
 5141                    .into_iter()
 5142                    .map(|presentation| ColorPresentation {
 5143                        label: SharedString::from(presentation.label),
 5144                        text_edit: presentation.text_edit,
 5145                        additional_text_edits: presentation
 5146                            .additional_text_edits
 5147                            .unwrap_or_default(),
 5148                    })
 5149                    .collect();
 5150                color.resolved = true;
 5151                Ok(color)
 5152            })
 5153        }
 5154    }
 5155
 5156    pub(crate) fn linked_edits(
 5157        &mut self,
 5158        buffer: &Entity<Buffer>,
 5159        position: Anchor,
 5160        cx: &mut Context<Self>,
 5161    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5162        let snapshot = buffer.read(cx).snapshot();
 5163        let scope = snapshot.language_scope_at(position);
 5164        let Some(server_id) = self
 5165            .as_local()
 5166            .and_then(|local| {
 5167                buffer.update(cx, |buffer, cx| {
 5168                    local
 5169                        .language_servers_for_buffer(buffer, cx)
 5170                        .filter(|(_, server)| {
 5171                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5172                        })
 5173                        .filter(|(adapter, _)| {
 5174                            scope
 5175                                .as_ref()
 5176                                .map(|scope| scope.language_allowed(&adapter.name))
 5177                                .unwrap_or(true)
 5178                        })
 5179                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5180                        .next()
 5181                })
 5182            })
 5183            .or_else(|| {
 5184                self.upstream_client()
 5185                    .is_some()
 5186                    .then_some(LanguageServerToQuery::FirstCapable)
 5187            })
 5188            .filter(|_| {
 5189                maybe!({
 5190                    let language = buffer.read(cx).language_at(position)?;
 5191                    Some(
 5192                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5193                            .linked_edits,
 5194                    )
 5195                }) == Some(true)
 5196            })
 5197        else {
 5198            return Task::ready(Ok(Vec::new()));
 5199        };
 5200
 5201        self.request_lsp(
 5202            buffer.clone(),
 5203            server_id,
 5204            LinkedEditingRange { position },
 5205            cx,
 5206        )
 5207    }
 5208
 5209    fn apply_on_type_formatting(
 5210        &mut self,
 5211        buffer: Entity<Buffer>,
 5212        position: Anchor,
 5213        trigger: String,
 5214        cx: &mut Context<Self>,
 5215    ) -> Task<Result<Option<Transaction>>> {
 5216        if let Some((client, project_id)) = self.upstream_client() {
 5217            if !self.check_if_capable_for_proto_request(
 5218                &buffer,
 5219                |capabilities| {
 5220                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5221                },
 5222                cx,
 5223            ) {
 5224                return Task::ready(Ok(None));
 5225            }
 5226            let request = proto::OnTypeFormatting {
 5227                project_id,
 5228                buffer_id: buffer.read(cx).remote_id().into(),
 5229                position: Some(serialize_anchor(&position)),
 5230                trigger,
 5231                version: serialize_version(&buffer.read(cx).version()),
 5232            };
 5233            cx.background_spawn(async move {
 5234                client
 5235                    .request(request)
 5236                    .await?
 5237                    .transaction
 5238                    .map(language::proto::deserialize_transaction)
 5239                    .transpose()
 5240            })
 5241        } else if let Some(local) = self.as_local_mut() {
 5242            let buffer_id = buffer.read(cx).remote_id();
 5243            local.buffers_being_formatted.insert(buffer_id);
 5244            cx.spawn(async move |this, cx| {
 5245                let _cleanup = defer({
 5246                    let this = this.clone();
 5247                    let mut cx = cx.clone();
 5248                    move || {
 5249                        this.update(&mut cx, |this, _| {
 5250                            if let Some(local) = this.as_local_mut() {
 5251                                local.buffers_being_formatted.remove(&buffer_id);
 5252                            }
 5253                        })
 5254                        .ok();
 5255                    }
 5256                });
 5257
 5258                buffer
 5259                    .update(cx, |buffer, _| {
 5260                        buffer.wait_for_edits(Some(position.timestamp))
 5261                    })?
 5262                    .await?;
 5263                this.update(cx, |this, cx| {
 5264                    let position = position.to_point_utf16(buffer.read(cx));
 5265                    this.on_type_format(buffer, position, trigger, false, cx)
 5266                })?
 5267                .await
 5268            })
 5269        } else {
 5270            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5271        }
 5272    }
 5273
 5274    pub fn on_type_format<T: ToPointUtf16>(
 5275        &mut self,
 5276        buffer: Entity<Buffer>,
 5277        position: T,
 5278        trigger: String,
 5279        push_to_history: bool,
 5280        cx: &mut Context<Self>,
 5281    ) -> Task<Result<Option<Transaction>>> {
 5282        let position = position.to_point_utf16(buffer.read(cx));
 5283        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5284    }
 5285
 5286    fn on_type_format_impl(
 5287        &mut self,
 5288        buffer: Entity<Buffer>,
 5289        position: PointUtf16,
 5290        trigger: String,
 5291        push_to_history: bool,
 5292        cx: &mut Context<Self>,
 5293    ) -> Task<Result<Option<Transaction>>> {
 5294        let options = buffer.update(cx, |buffer, cx| {
 5295            lsp_command::lsp_formatting_options(
 5296                language_settings(
 5297                    buffer.language_at(position).map(|l| l.name()),
 5298                    buffer.file(),
 5299                    cx,
 5300                )
 5301                .as_ref(),
 5302            )
 5303        });
 5304
 5305        cx.spawn(async move |this, cx| {
 5306            if let Some(waiter) =
 5307                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5308            {
 5309                waiter.await?;
 5310            }
 5311            cx.update(|cx| {
 5312                this.update(cx, |this, cx| {
 5313                    this.request_lsp(
 5314                        buffer.clone(),
 5315                        LanguageServerToQuery::FirstCapable,
 5316                        OnTypeFormatting {
 5317                            position,
 5318                            trigger,
 5319                            options,
 5320                            push_to_history,
 5321                        },
 5322                        cx,
 5323                    )
 5324                })
 5325            })??
 5326            .await
 5327        })
 5328    }
 5329
 5330    pub fn definitions(
 5331        &mut self,
 5332        buffer: &Entity<Buffer>,
 5333        position: PointUtf16,
 5334        cx: &mut Context<Self>,
 5335    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5336        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5337            let request = GetDefinitions { position };
 5338            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5339                return Task::ready(Ok(None));
 5340            }
 5341            let request_task = upstream_client.request_lsp(
 5342                project_id,
 5343                None,
 5344                LSP_REQUEST_TIMEOUT,
 5345                cx.background_executor().clone(),
 5346                request.to_proto(project_id, buffer.read(cx)),
 5347            );
 5348            let buffer = buffer.clone();
 5349            cx.spawn(async move |weak_lsp_store, cx| {
 5350                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5351                    return Ok(None);
 5352                };
 5353                let Some(responses) = request_task.await? else {
 5354                    return Ok(None);
 5355                };
 5356                let actions = join_all(responses.payload.into_iter().map(|response| {
 5357                    GetDefinitions { position }.response_from_proto(
 5358                        response.response,
 5359                        lsp_store.clone(),
 5360                        buffer.clone(),
 5361                        cx.clone(),
 5362                    )
 5363                }))
 5364                .await;
 5365
 5366                Ok(Some(
 5367                    actions
 5368                        .into_iter()
 5369                        .collect::<Result<Vec<Vec<_>>>>()?
 5370                        .into_iter()
 5371                        .flatten()
 5372                        .dedup()
 5373                        .collect(),
 5374                ))
 5375            })
 5376        } else {
 5377            let definitions_task = self.request_multiple_lsp_locally(
 5378                buffer,
 5379                Some(position),
 5380                GetDefinitions { position },
 5381                cx,
 5382            );
 5383            cx.background_spawn(async move {
 5384                Ok(Some(
 5385                    definitions_task
 5386                        .await
 5387                        .into_iter()
 5388                        .flat_map(|(_, definitions)| definitions)
 5389                        .dedup()
 5390                        .collect(),
 5391                ))
 5392            })
 5393        }
 5394    }
 5395
 5396    pub fn declarations(
 5397        &mut self,
 5398        buffer: &Entity<Buffer>,
 5399        position: PointUtf16,
 5400        cx: &mut Context<Self>,
 5401    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5402        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5403            let request = GetDeclarations { position };
 5404            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5405                return Task::ready(Ok(None));
 5406            }
 5407            let request_task = upstream_client.request_lsp(
 5408                project_id,
 5409                None,
 5410                LSP_REQUEST_TIMEOUT,
 5411                cx.background_executor().clone(),
 5412                request.to_proto(project_id, buffer.read(cx)),
 5413            );
 5414            let buffer = buffer.clone();
 5415            cx.spawn(async move |weak_lsp_store, cx| {
 5416                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5417                    return Ok(None);
 5418                };
 5419                let Some(responses) = request_task.await? else {
 5420                    return Ok(None);
 5421                };
 5422                let actions = join_all(responses.payload.into_iter().map(|response| {
 5423                    GetDeclarations { position }.response_from_proto(
 5424                        response.response,
 5425                        lsp_store.clone(),
 5426                        buffer.clone(),
 5427                        cx.clone(),
 5428                    )
 5429                }))
 5430                .await;
 5431
 5432                Ok(Some(
 5433                    actions
 5434                        .into_iter()
 5435                        .collect::<Result<Vec<Vec<_>>>>()?
 5436                        .into_iter()
 5437                        .flatten()
 5438                        .dedup()
 5439                        .collect(),
 5440                ))
 5441            })
 5442        } else {
 5443            let declarations_task = self.request_multiple_lsp_locally(
 5444                buffer,
 5445                Some(position),
 5446                GetDeclarations { position },
 5447                cx,
 5448            );
 5449            cx.background_spawn(async move {
 5450                Ok(Some(
 5451                    declarations_task
 5452                        .await
 5453                        .into_iter()
 5454                        .flat_map(|(_, declarations)| declarations)
 5455                        .dedup()
 5456                        .collect(),
 5457                ))
 5458            })
 5459        }
 5460    }
 5461
 5462    pub fn type_definitions(
 5463        &mut self,
 5464        buffer: &Entity<Buffer>,
 5465        position: PointUtf16,
 5466        cx: &mut Context<Self>,
 5467    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5468        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5469            let request = GetTypeDefinitions { position };
 5470            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5471                return Task::ready(Ok(None));
 5472            }
 5473            let request_task = upstream_client.request_lsp(
 5474                project_id,
 5475                None,
 5476                LSP_REQUEST_TIMEOUT,
 5477                cx.background_executor().clone(),
 5478                request.to_proto(project_id, buffer.read(cx)),
 5479            );
 5480            let buffer = buffer.clone();
 5481            cx.spawn(async move |weak_lsp_store, cx| {
 5482                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5483                    return Ok(None);
 5484                };
 5485                let Some(responses) = request_task.await? else {
 5486                    return Ok(None);
 5487                };
 5488                let actions = join_all(responses.payload.into_iter().map(|response| {
 5489                    GetTypeDefinitions { position }.response_from_proto(
 5490                        response.response,
 5491                        lsp_store.clone(),
 5492                        buffer.clone(),
 5493                        cx.clone(),
 5494                    )
 5495                }))
 5496                .await;
 5497
 5498                Ok(Some(
 5499                    actions
 5500                        .into_iter()
 5501                        .collect::<Result<Vec<Vec<_>>>>()?
 5502                        .into_iter()
 5503                        .flatten()
 5504                        .dedup()
 5505                        .collect(),
 5506                ))
 5507            })
 5508        } else {
 5509            let type_definitions_task = self.request_multiple_lsp_locally(
 5510                buffer,
 5511                Some(position),
 5512                GetTypeDefinitions { position },
 5513                cx,
 5514            );
 5515            cx.background_spawn(async move {
 5516                Ok(Some(
 5517                    type_definitions_task
 5518                        .await
 5519                        .into_iter()
 5520                        .flat_map(|(_, type_definitions)| type_definitions)
 5521                        .dedup()
 5522                        .collect(),
 5523                ))
 5524            })
 5525        }
 5526    }
 5527
 5528    pub fn implementations(
 5529        &mut self,
 5530        buffer: &Entity<Buffer>,
 5531        position: PointUtf16,
 5532        cx: &mut Context<Self>,
 5533    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5534        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5535            let request = GetImplementations { position };
 5536            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5537                return Task::ready(Ok(None));
 5538            }
 5539            let request_task = upstream_client.request_lsp(
 5540                project_id,
 5541                None,
 5542                LSP_REQUEST_TIMEOUT,
 5543                cx.background_executor().clone(),
 5544                request.to_proto(project_id, buffer.read(cx)),
 5545            );
 5546            let buffer = buffer.clone();
 5547            cx.spawn(async move |weak_lsp_store, cx| {
 5548                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5549                    return Ok(None);
 5550                };
 5551                let Some(responses) = request_task.await? else {
 5552                    return Ok(None);
 5553                };
 5554                let actions = join_all(responses.payload.into_iter().map(|response| {
 5555                    GetImplementations { position }.response_from_proto(
 5556                        response.response,
 5557                        lsp_store.clone(),
 5558                        buffer.clone(),
 5559                        cx.clone(),
 5560                    )
 5561                }))
 5562                .await;
 5563
 5564                Ok(Some(
 5565                    actions
 5566                        .into_iter()
 5567                        .collect::<Result<Vec<Vec<_>>>>()?
 5568                        .into_iter()
 5569                        .flatten()
 5570                        .dedup()
 5571                        .collect(),
 5572                ))
 5573            })
 5574        } else {
 5575            let implementations_task = self.request_multiple_lsp_locally(
 5576                buffer,
 5577                Some(position),
 5578                GetImplementations { position },
 5579                cx,
 5580            );
 5581            cx.background_spawn(async move {
 5582                Ok(Some(
 5583                    implementations_task
 5584                        .await
 5585                        .into_iter()
 5586                        .flat_map(|(_, implementations)| implementations)
 5587                        .dedup()
 5588                        .collect(),
 5589                ))
 5590            })
 5591        }
 5592    }
 5593
 5594    pub fn references(
 5595        &mut self,
 5596        buffer: &Entity<Buffer>,
 5597        position: PointUtf16,
 5598        cx: &mut Context<Self>,
 5599    ) -> Task<Result<Option<Vec<Location>>>> {
 5600        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5601            let request = GetReferences { position };
 5602            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5603                return Task::ready(Ok(None));
 5604            }
 5605
 5606            let request_task = upstream_client.request_lsp(
 5607                project_id,
 5608                None,
 5609                LSP_REQUEST_TIMEOUT,
 5610                cx.background_executor().clone(),
 5611                request.to_proto(project_id, buffer.read(cx)),
 5612            );
 5613            let buffer = buffer.clone();
 5614            cx.spawn(async move |weak_lsp_store, cx| {
 5615                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5616                    return Ok(None);
 5617                };
 5618                let Some(responses) = request_task.await? else {
 5619                    return Ok(None);
 5620                };
 5621
 5622                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5623                    GetReferences { position }.response_from_proto(
 5624                        lsp_response.response,
 5625                        lsp_store.clone(),
 5626                        buffer.clone(),
 5627                        cx.clone(),
 5628                    )
 5629                }))
 5630                .await
 5631                .into_iter()
 5632                .collect::<Result<Vec<Vec<_>>>>()?
 5633                .into_iter()
 5634                .flatten()
 5635                .dedup()
 5636                .collect();
 5637                Ok(Some(locations))
 5638            })
 5639        } else {
 5640            let references_task = self.request_multiple_lsp_locally(
 5641                buffer,
 5642                Some(position),
 5643                GetReferences { position },
 5644                cx,
 5645            );
 5646            cx.background_spawn(async move {
 5647                Ok(Some(
 5648                    references_task
 5649                        .await
 5650                        .into_iter()
 5651                        .flat_map(|(_, references)| references)
 5652                        .dedup()
 5653                        .collect(),
 5654                ))
 5655            })
 5656        }
 5657    }
 5658
 5659    pub fn code_actions(
 5660        &mut self,
 5661        buffer: &Entity<Buffer>,
 5662        range: Range<Anchor>,
 5663        kinds: Option<Vec<CodeActionKind>>,
 5664        cx: &mut Context<Self>,
 5665    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5666        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5667            let request = GetCodeActions {
 5668                range: range.clone(),
 5669                kinds: kinds.clone(),
 5670            };
 5671            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5672                return Task::ready(Ok(None));
 5673            }
 5674            let request_task = upstream_client.request_lsp(
 5675                project_id,
 5676                None,
 5677                LSP_REQUEST_TIMEOUT,
 5678                cx.background_executor().clone(),
 5679                request.to_proto(project_id, buffer.read(cx)),
 5680            );
 5681            let buffer = buffer.clone();
 5682            cx.spawn(async move |weak_lsp_store, cx| {
 5683                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5684                    return Ok(None);
 5685                };
 5686                let Some(responses) = request_task.await? else {
 5687                    return Ok(None);
 5688                };
 5689                let actions = join_all(responses.payload.into_iter().map(|response| {
 5690                    GetCodeActions {
 5691                        range: range.clone(),
 5692                        kinds: kinds.clone(),
 5693                    }
 5694                    .response_from_proto(
 5695                        response.response,
 5696                        lsp_store.clone(),
 5697                        buffer.clone(),
 5698                        cx.clone(),
 5699                    )
 5700                }))
 5701                .await;
 5702
 5703                Ok(Some(
 5704                    actions
 5705                        .into_iter()
 5706                        .collect::<Result<Vec<Vec<_>>>>()?
 5707                        .into_iter()
 5708                        .flatten()
 5709                        .collect(),
 5710                ))
 5711            })
 5712        } else {
 5713            let all_actions_task = self.request_multiple_lsp_locally(
 5714                buffer,
 5715                Some(range.start),
 5716                GetCodeActions { range, kinds },
 5717                cx,
 5718            );
 5719            cx.background_spawn(async move {
 5720                Ok(Some(
 5721                    all_actions_task
 5722                        .await
 5723                        .into_iter()
 5724                        .flat_map(|(_, actions)| actions)
 5725                        .collect(),
 5726                ))
 5727            })
 5728        }
 5729    }
 5730
 5731    pub fn code_lens_actions(
 5732        &mut self,
 5733        buffer: &Entity<Buffer>,
 5734        cx: &mut Context<Self>,
 5735    ) -> CodeLensTask {
 5736        let version_queried_for = buffer.read(cx).version();
 5737        let buffer_id = buffer.read(cx).remote_id();
 5738        let existing_servers = self.as_local().map(|local| {
 5739            local
 5740                .buffers_opened_in_servers
 5741                .get(&buffer_id)
 5742                .cloned()
 5743                .unwrap_or_default()
 5744        });
 5745
 5746        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5747            if let Some(cached_lens) = &lsp_data.code_lens {
 5748                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5749                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5750                        existing_servers != cached_lens.lens.keys().copied().collect()
 5751                    });
 5752                    if !has_different_servers {
 5753                        return Task::ready(Ok(Some(
 5754                            cached_lens.lens.values().flatten().cloned().collect(),
 5755                        )))
 5756                        .shared();
 5757                    }
 5758                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5759                    if !version_queried_for.changed_since(updating_for) {
 5760                        return running_update.clone();
 5761                    }
 5762                }
 5763            }
 5764        }
 5765
 5766        let lens_lsp_data = self
 5767            .latest_lsp_data(buffer, cx)
 5768            .code_lens
 5769            .get_or_insert_default();
 5770        let buffer = buffer.clone();
 5771        let query_version_queried_for = version_queried_for.clone();
 5772        let new_task = cx
 5773            .spawn(async move |lsp_store, cx| {
 5774                cx.background_executor()
 5775                    .timer(Duration::from_millis(30))
 5776                    .await;
 5777                let fetched_lens = lsp_store
 5778                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5779                    .map_err(Arc::new)?
 5780                    .await
 5781                    .context("fetching code lens")
 5782                    .map_err(Arc::new);
 5783                let fetched_lens = match fetched_lens {
 5784                    Ok(fetched_lens) => fetched_lens,
 5785                    Err(e) => {
 5786                        lsp_store
 5787                            .update(cx, |lsp_store, _| {
 5788                                if let Some(lens_lsp_data) = lsp_store
 5789                                    .lsp_data
 5790                                    .get_mut(&buffer_id)
 5791                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5792                                {
 5793                                    lens_lsp_data.update = None;
 5794                                }
 5795                            })
 5796                            .ok();
 5797                        return Err(e);
 5798                    }
 5799                };
 5800
 5801                lsp_store
 5802                    .update(cx, |lsp_store, _| {
 5803                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5804                        let code_lens = lsp_data.code_lens.as_mut()?;
 5805                        if let Some(fetched_lens) = fetched_lens {
 5806                            if lsp_data.buffer_version == query_version_queried_for {
 5807                                code_lens.lens.extend(fetched_lens);
 5808                            } else if !lsp_data
 5809                                .buffer_version
 5810                                .changed_since(&query_version_queried_for)
 5811                            {
 5812                                lsp_data.buffer_version = query_version_queried_for;
 5813                                code_lens.lens = fetched_lens;
 5814                            }
 5815                        }
 5816                        code_lens.update = None;
 5817                        Some(code_lens.lens.values().flatten().cloned().collect())
 5818                    })
 5819                    .map_err(Arc::new)
 5820            })
 5821            .shared();
 5822        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5823        new_task
 5824    }
 5825
 5826    fn fetch_code_lens(
 5827        &mut self,
 5828        buffer: &Entity<Buffer>,
 5829        cx: &mut Context<Self>,
 5830    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5831        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5832            let request = GetCodeLens;
 5833            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5834                return Task::ready(Ok(None));
 5835            }
 5836            let request_task = upstream_client.request_lsp(
 5837                project_id,
 5838                None,
 5839                LSP_REQUEST_TIMEOUT,
 5840                cx.background_executor().clone(),
 5841                request.to_proto(project_id, buffer.read(cx)),
 5842            );
 5843            let buffer = buffer.clone();
 5844            cx.spawn(async move |weak_lsp_store, cx| {
 5845                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5846                    return Ok(None);
 5847                };
 5848                let Some(responses) = request_task.await? else {
 5849                    return Ok(None);
 5850                };
 5851
 5852                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5853                    let lsp_store = lsp_store.clone();
 5854                    let buffer = buffer.clone();
 5855                    let cx = cx.clone();
 5856                    async move {
 5857                        (
 5858                            LanguageServerId::from_proto(response.server_id),
 5859                            GetCodeLens
 5860                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5861                                .await,
 5862                        )
 5863                    }
 5864                }))
 5865                .await;
 5866
 5867                let mut has_errors = false;
 5868                let code_lens_actions = code_lens_actions
 5869                    .into_iter()
 5870                    .filter_map(|(server_id, code_lens)| match code_lens {
 5871                        Ok(code_lens) => Some((server_id, code_lens)),
 5872                        Err(e) => {
 5873                            has_errors = true;
 5874                            log::error!("{e:#}");
 5875                            None
 5876                        }
 5877                    })
 5878                    .collect::<HashMap<_, _>>();
 5879                anyhow::ensure!(
 5880                    !has_errors || !code_lens_actions.is_empty(),
 5881                    "Failed to fetch code lens"
 5882                );
 5883                Ok(Some(code_lens_actions))
 5884            })
 5885        } else {
 5886            let code_lens_actions_task =
 5887                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5888            cx.background_spawn(async move {
 5889                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5890            })
 5891        }
 5892    }
 5893
 5894    #[inline(never)]
 5895    pub fn completions(
 5896        &self,
 5897        buffer: &Entity<Buffer>,
 5898        position: PointUtf16,
 5899        context: CompletionContext,
 5900        cx: &mut Context<Self>,
 5901    ) -> Task<Result<Vec<CompletionResponse>>> {
 5902        let language_registry = self.languages.clone();
 5903
 5904        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5905            let request = GetCompletions { position, context };
 5906            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5907                return Task::ready(Ok(Vec::new()));
 5908            }
 5909            let task = self.send_lsp_proto_request(
 5910                buffer.clone(),
 5911                upstream_client,
 5912                project_id,
 5913                request,
 5914                cx,
 5915            );
 5916            let language = buffer.read(cx).language().cloned();
 5917
 5918            // In the future, we should provide project guests with the names of LSP adapters,
 5919            // so that they can use the correct LSP adapter when computing labels. For now,
 5920            // guests just use the first LSP adapter associated with the buffer's language.
 5921            let lsp_adapter = language.as_ref().and_then(|language| {
 5922                language_registry
 5923                    .lsp_adapters(&language.name())
 5924                    .first()
 5925                    .cloned()
 5926            });
 5927
 5928            cx.foreground_executor().spawn(async move {
 5929                let completion_response = task.await?;
 5930                let completions = populate_labels_for_completions(
 5931                    completion_response.completions,
 5932                    language,
 5933                    lsp_adapter,
 5934                )
 5935                .await;
 5936                Ok(vec![CompletionResponse {
 5937                    completions,
 5938                    display_options: CompletionDisplayOptions::default(),
 5939                    is_incomplete: completion_response.is_incomplete,
 5940                }])
 5941            })
 5942        } else if let Some(local) = self.as_local() {
 5943            let snapshot = buffer.read(cx).snapshot();
 5944            let offset = position.to_offset(&snapshot);
 5945            let scope = snapshot.language_scope_at(offset);
 5946            let language = snapshot.language().cloned();
 5947            let completion_settings = language_settings(
 5948                language.as_ref().map(|language| language.name()),
 5949                buffer.read(cx).file(),
 5950                cx,
 5951            )
 5952            .completions
 5953            .clone();
 5954            if !completion_settings.lsp {
 5955                return Task::ready(Ok(Vec::new()));
 5956            }
 5957
 5958            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5959                local
 5960                    .language_servers_for_buffer(buffer, cx)
 5961                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5962                    .filter(|(adapter, _)| {
 5963                        scope
 5964                            .as_ref()
 5965                            .map(|scope| scope.language_allowed(&adapter.name))
 5966                            .unwrap_or(true)
 5967                    })
 5968                    .map(|(_, server)| server.server_id())
 5969                    .collect()
 5970            });
 5971
 5972            let buffer = buffer.clone();
 5973            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5974            let lsp_timeout = if lsp_timeout > 0 {
 5975                Some(Duration::from_millis(lsp_timeout))
 5976            } else {
 5977                None
 5978            };
 5979            cx.spawn(async move |this,  cx| {
 5980                let mut tasks = Vec::with_capacity(server_ids.len());
 5981                this.update(cx, |lsp_store, cx| {
 5982                    for server_id in server_ids {
 5983                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5984                        let lsp_timeout = lsp_timeout
 5985                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5986                        let mut timeout = cx.background_spawn(async move {
 5987                            match lsp_timeout {
 5988                                Some(lsp_timeout) => {
 5989                                    lsp_timeout.await;
 5990                                    true
 5991                                },
 5992                                None => false,
 5993                            }
 5994                        }).fuse();
 5995                        let mut lsp_request = lsp_store.request_lsp(
 5996                            buffer.clone(),
 5997                            LanguageServerToQuery::Other(server_id),
 5998                            GetCompletions {
 5999                                position,
 6000                                context: context.clone(),
 6001                            },
 6002                            cx,
 6003                        ).fuse();
 6004                        let new_task = cx.background_spawn(async move {
 6005                            select_biased! {
 6006                                response = lsp_request => anyhow::Ok(Some(response?)),
 6007                                timeout_happened = timeout => {
 6008                                    if timeout_happened {
 6009                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6010                                        Ok(None)
 6011                                    } else {
 6012                                        let completions = lsp_request.await?;
 6013                                        Ok(Some(completions))
 6014                                    }
 6015                                },
 6016                            }
 6017                        });
 6018                        tasks.push((lsp_adapter, new_task));
 6019                    }
 6020                })?;
 6021
 6022                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6023                    let completion_response = task.await.ok()??;
 6024                    let completions = populate_labels_for_completions(
 6025                            completion_response.completions,
 6026                            language.clone(),
 6027                            lsp_adapter,
 6028                        )
 6029                        .await;
 6030                    Some(CompletionResponse {
 6031                        completions,
 6032                        display_options: CompletionDisplayOptions::default(),
 6033                        is_incomplete: completion_response.is_incomplete,
 6034                    })
 6035                });
 6036
 6037                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6038
 6039                Ok(responses.into_iter().flatten().collect())
 6040            })
 6041        } else {
 6042            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6043        }
 6044    }
 6045
 6046    pub fn resolve_completions(
 6047        &self,
 6048        buffer: Entity<Buffer>,
 6049        completion_indices: Vec<usize>,
 6050        completions: Rc<RefCell<Box<[Completion]>>>,
 6051        cx: &mut Context<Self>,
 6052    ) -> Task<Result<bool>> {
 6053        let client = self.upstream_client();
 6054        let buffer_id = buffer.read(cx).remote_id();
 6055        let buffer_snapshot = buffer.read(cx).snapshot();
 6056
 6057        if !self.check_if_capable_for_proto_request(
 6058            &buffer,
 6059            GetCompletions::can_resolve_completions,
 6060            cx,
 6061        ) {
 6062            return Task::ready(Ok(false));
 6063        }
 6064        cx.spawn(async move |lsp_store, cx| {
 6065            let mut did_resolve = false;
 6066            if let Some((client, project_id)) = client {
 6067                for completion_index in completion_indices {
 6068                    let server_id = {
 6069                        let completion = &completions.borrow()[completion_index];
 6070                        completion.source.server_id()
 6071                    };
 6072                    if let Some(server_id) = server_id {
 6073                        if Self::resolve_completion_remote(
 6074                            project_id,
 6075                            server_id,
 6076                            buffer_id,
 6077                            completions.clone(),
 6078                            completion_index,
 6079                            client.clone(),
 6080                        )
 6081                        .await
 6082                        .log_err()
 6083                        .is_some()
 6084                        {
 6085                            did_resolve = true;
 6086                        }
 6087                    } else {
 6088                        resolve_word_completion(
 6089                            &buffer_snapshot,
 6090                            &mut completions.borrow_mut()[completion_index],
 6091                        );
 6092                    }
 6093                }
 6094            } else {
 6095                for completion_index in completion_indices {
 6096                    let server_id = {
 6097                        let completion = &completions.borrow()[completion_index];
 6098                        completion.source.server_id()
 6099                    };
 6100                    if let Some(server_id) = server_id {
 6101                        let server_and_adapter = lsp_store
 6102                            .read_with(cx, |lsp_store, _| {
 6103                                let server = lsp_store.language_server_for_id(server_id)?;
 6104                                let adapter =
 6105                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6106                                Some((server, adapter))
 6107                            })
 6108                            .ok()
 6109                            .flatten();
 6110                        let Some((server, adapter)) = server_and_adapter else {
 6111                            continue;
 6112                        };
 6113
 6114                        let resolved = Self::resolve_completion_local(
 6115                            server,
 6116                            completions.clone(),
 6117                            completion_index,
 6118                        )
 6119                        .await
 6120                        .log_err()
 6121                        .is_some();
 6122                        if resolved {
 6123                            Self::regenerate_completion_labels(
 6124                                adapter,
 6125                                &buffer_snapshot,
 6126                                completions.clone(),
 6127                                completion_index,
 6128                            )
 6129                            .await
 6130                            .log_err();
 6131                            did_resolve = true;
 6132                        }
 6133                    } else {
 6134                        resolve_word_completion(
 6135                            &buffer_snapshot,
 6136                            &mut completions.borrow_mut()[completion_index],
 6137                        );
 6138                    }
 6139                }
 6140            }
 6141
 6142            Ok(did_resolve)
 6143        })
 6144    }
 6145
 6146    async fn resolve_completion_local(
 6147        server: Arc<lsp::LanguageServer>,
 6148        completions: Rc<RefCell<Box<[Completion]>>>,
 6149        completion_index: usize,
 6150    ) -> Result<()> {
 6151        let server_id = server.server_id();
 6152        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6153            return Ok(());
 6154        }
 6155
 6156        let request = {
 6157            let completion = &completions.borrow()[completion_index];
 6158            match &completion.source {
 6159                CompletionSource::Lsp {
 6160                    lsp_completion,
 6161                    resolved,
 6162                    server_id: completion_server_id,
 6163                    ..
 6164                } => {
 6165                    if *resolved {
 6166                        return Ok(());
 6167                    }
 6168                    anyhow::ensure!(
 6169                        server_id == *completion_server_id,
 6170                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6171                    );
 6172                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6173                }
 6174                CompletionSource::BufferWord { .. }
 6175                | CompletionSource::Dap { .. }
 6176                | CompletionSource::Custom => {
 6177                    return Ok(());
 6178                }
 6179            }
 6180        };
 6181        let resolved_completion = request
 6182            .await
 6183            .into_response()
 6184            .context("resolve completion")?;
 6185
 6186        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6187        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6188
 6189        let mut completions = completions.borrow_mut();
 6190        let completion = &mut completions[completion_index];
 6191        if let CompletionSource::Lsp {
 6192            lsp_completion,
 6193            resolved,
 6194            server_id: completion_server_id,
 6195            ..
 6196        } = &mut completion.source
 6197        {
 6198            if *resolved {
 6199                return Ok(());
 6200            }
 6201            anyhow::ensure!(
 6202                server_id == *completion_server_id,
 6203                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6204            );
 6205            *lsp_completion = Box::new(resolved_completion);
 6206            *resolved = true;
 6207        }
 6208        Ok(())
 6209    }
 6210
 6211    async fn regenerate_completion_labels(
 6212        adapter: Arc<CachedLspAdapter>,
 6213        snapshot: &BufferSnapshot,
 6214        completions: Rc<RefCell<Box<[Completion]>>>,
 6215        completion_index: usize,
 6216    ) -> Result<()> {
 6217        let completion_item = completions.borrow()[completion_index]
 6218            .source
 6219            .lsp_completion(true)
 6220            .map(Cow::into_owned);
 6221        if let Some(lsp_documentation) = completion_item
 6222            .as_ref()
 6223            .and_then(|completion_item| completion_item.documentation.clone())
 6224        {
 6225            let mut completions = completions.borrow_mut();
 6226            let completion = &mut completions[completion_index];
 6227            completion.documentation = Some(lsp_documentation.into());
 6228        } else {
 6229            let mut completions = completions.borrow_mut();
 6230            let completion = &mut completions[completion_index];
 6231            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6232        }
 6233
 6234        let mut new_label = match completion_item {
 6235            Some(completion_item) => {
 6236                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6237                // So we have to update the label here anyway...
 6238                let language = snapshot.language();
 6239                match language {
 6240                    Some(language) => {
 6241                        adapter
 6242                            .labels_for_completions(
 6243                                std::slice::from_ref(&completion_item),
 6244                                language,
 6245                            )
 6246                            .await?
 6247                    }
 6248                    None => Vec::new(),
 6249                }
 6250                .pop()
 6251                .flatten()
 6252                .unwrap_or_else(|| {
 6253                    CodeLabel::fallback_for_completion(
 6254                        &completion_item,
 6255                        language.map(|language| language.as_ref()),
 6256                    )
 6257                })
 6258            }
 6259            None => CodeLabel::plain(
 6260                completions.borrow()[completion_index].new_text.clone(),
 6261                None,
 6262            ),
 6263        };
 6264        ensure_uniform_list_compatible_label(&mut new_label);
 6265
 6266        let mut completions = completions.borrow_mut();
 6267        let completion = &mut completions[completion_index];
 6268        if completion.label.filter_text() == new_label.filter_text() {
 6269            completion.label = new_label;
 6270        } else {
 6271            log::error!(
 6272                "Resolved completion changed display label from {} to {}. \
 6273                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6274                completion.label.text(),
 6275                new_label.text(),
 6276                completion.label.filter_text(),
 6277                new_label.filter_text()
 6278            );
 6279        }
 6280
 6281        Ok(())
 6282    }
 6283
 6284    async fn resolve_completion_remote(
 6285        project_id: u64,
 6286        server_id: LanguageServerId,
 6287        buffer_id: BufferId,
 6288        completions: Rc<RefCell<Box<[Completion]>>>,
 6289        completion_index: usize,
 6290        client: AnyProtoClient,
 6291    ) -> Result<()> {
 6292        let lsp_completion = {
 6293            let completion = &completions.borrow()[completion_index];
 6294            match &completion.source {
 6295                CompletionSource::Lsp {
 6296                    lsp_completion,
 6297                    resolved,
 6298                    server_id: completion_server_id,
 6299                    ..
 6300                } => {
 6301                    anyhow::ensure!(
 6302                        server_id == *completion_server_id,
 6303                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6304                    );
 6305                    if *resolved {
 6306                        return Ok(());
 6307                    }
 6308                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6309                }
 6310                CompletionSource::Custom
 6311                | CompletionSource::Dap { .. }
 6312                | CompletionSource::BufferWord { .. } => {
 6313                    return Ok(());
 6314                }
 6315            }
 6316        };
 6317        let request = proto::ResolveCompletionDocumentation {
 6318            project_id,
 6319            language_server_id: server_id.0 as u64,
 6320            lsp_completion,
 6321            buffer_id: buffer_id.into(),
 6322        };
 6323
 6324        let response = client
 6325            .request(request)
 6326            .await
 6327            .context("completion documentation resolve proto request")?;
 6328        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6329
 6330        let documentation = if response.documentation.is_empty() {
 6331            CompletionDocumentation::Undocumented
 6332        } else if response.documentation_is_markdown {
 6333            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6334        } else if response.documentation.lines().count() <= 1 {
 6335            CompletionDocumentation::SingleLine(response.documentation.into())
 6336        } else {
 6337            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6338        };
 6339
 6340        let mut completions = completions.borrow_mut();
 6341        let completion = &mut completions[completion_index];
 6342        completion.documentation = Some(documentation);
 6343        if let CompletionSource::Lsp {
 6344            insert_range,
 6345            lsp_completion,
 6346            resolved,
 6347            server_id: completion_server_id,
 6348            lsp_defaults: _,
 6349        } = &mut completion.source
 6350        {
 6351            let completion_insert_range = response
 6352                .old_insert_start
 6353                .and_then(deserialize_anchor)
 6354                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6355            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6356
 6357            if *resolved {
 6358                return Ok(());
 6359            }
 6360            anyhow::ensure!(
 6361                server_id == *completion_server_id,
 6362                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6363            );
 6364            *lsp_completion = Box::new(resolved_lsp_completion);
 6365            *resolved = true;
 6366        }
 6367
 6368        let replace_range = response
 6369            .old_replace_start
 6370            .and_then(deserialize_anchor)
 6371            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6372        if let Some((old_replace_start, old_replace_end)) = replace_range
 6373            && !response.new_text.is_empty()
 6374        {
 6375            completion.new_text = response.new_text;
 6376            completion.replace_range = old_replace_start..old_replace_end;
 6377        }
 6378
 6379        Ok(())
 6380    }
 6381
 6382    pub fn apply_additional_edits_for_completion(
 6383        &self,
 6384        buffer_handle: Entity<Buffer>,
 6385        completions: Rc<RefCell<Box<[Completion]>>>,
 6386        completion_index: usize,
 6387        push_to_history: bool,
 6388        cx: &mut Context<Self>,
 6389    ) -> Task<Result<Option<Transaction>>> {
 6390        if let Some((client, project_id)) = self.upstream_client() {
 6391            let buffer = buffer_handle.read(cx);
 6392            let buffer_id = buffer.remote_id();
 6393            cx.spawn(async move |_, cx| {
 6394                let request = {
 6395                    let completion = completions.borrow()[completion_index].clone();
 6396                    proto::ApplyCompletionAdditionalEdits {
 6397                        project_id,
 6398                        buffer_id: buffer_id.into(),
 6399                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6400                            replace_range: completion.replace_range,
 6401                            new_text: completion.new_text,
 6402                            source: completion.source,
 6403                        })),
 6404                    }
 6405                };
 6406
 6407                if let Some(transaction) = client.request(request).await?.transaction {
 6408                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6409                    buffer_handle
 6410                        .update(cx, |buffer, _| {
 6411                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6412                        })?
 6413                        .await?;
 6414                    if push_to_history {
 6415                        buffer_handle.update(cx, |buffer, _| {
 6416                            buffer.push_transaction(transaction.clone(), Instant::now());
 6417                            buffer.finalize_last_transaction();
 6418                        })?;
 6419                    }
 6420                    Ok(Some(transaction))
 6421                } else {
 6422                    Ok(None)
 6423                }
 6424            })
 6425        } else {
 6426            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6427                let completion = &completions.borrow()[completion_index];
 6428                let server_id = completion.source.server_id()?;
 6429                Some(
 6430                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6431                        .1
 6432                        .clone(),
 6433                )
 6434            }) else {
 6435                return Task::ready(Ok(None));
 6436            };
 6437
 6438            cx.spawn(async move |this, cx| {
 6439                Self::resolve_completion_local(
 6440                    server.clone(),
 6441                    completions.clone(),
 6442                    completion_index,
 6443                )
 6444                .await
 6445                .context("resolving completion")?;
 6446                let completion = completions.borrow()[completion_index].clone();
 6447                let additional_text_edits = completion
 6448                    .source
 6449                    .lsp_completion(true)
 6450                    .as_ref()
 6451                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6452                if let Some(edits) = additional_text_edits {
 6453                    let edits = this
 6454                        .update(cx, |this, cx| {
 6455                            this.as_local_mut().unwrap().edits_from_lsp(
 6456                                &buffer_handle,
 6457                                edits,
 6458                                server.server_id(),
 6459                                None,
 6460                                cx,
 6461                            )
 6462                        })?
 6463                        .await?;
 6464
 6465                    buffer_handle.update(cx, |buffer, cx| {
 6466                        buffer.finalize_last_transaction();
 6467                        buffer.start_transaction();
 6468
 6469                        for (range, text) in edits {
 6470                            let primary = &completion.replace_range;
 6471
 6472                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6473                            // and the primary completion is just an insertion (empty range), then this is likely
 6474                            // an auto-import scenario and should not be considered overlapping
 6475                            // https://github.com/zed-industries/zed/issues/26136
 6476                            let is_file_start_auto_import = {
 6477                                let snapshot = buffer.snapshot();
 6478                                let primary_start_point = primary.start.to_point(&snapshot);
 6479                                let range_start_point = range.start.to_point(&snapshot);
 6480
 6481                                let result = primary_start_point.row == 0
 6482                                    && primary_start_point.column == 0
 6483                                    && range_start_point.row == 0
 6484                                    && range_start_point.column == 0;
 6485
 6486                                result
 6487                            };
 6488
 6489                            let has_overlap = if is_file_start_auto_import {
 6490                                false
 6491                            } else {
 6492                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6493                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6494                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6495                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6496                                let result = start_within || end_within;
 6497                                result
 6498                            };
 6499
 6500                            //Skip additional edits which overlap with the primary completion edit
 6501                            //https://github.com/zed-industries/zed/pull/1871
 6502                            if !has_overlap {
 6503                                buffer.edit([(range, text)], None, cx);
 6504                            }
 6505                        }
 6506
 6507                        let transaction = if buffer.end_transaction(cx).is_some() {
 6508                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6509                            if !push_to_history {
 6510                                buffer.forget_transaction(transaction.id);
 6511                            }
 6512                            Some(transaction)
 6513                        } else {
 6514                            None
 6515                        };
 6516                        Ok(transaction)
 6517                    })?
 6518                } else {
 6519                    Ok(None)
 6520                }
 6521            })
 6522        }
 6523    }
 6524
 6525    pub fn pull_diagnostics(
 6526        &mut self,
 6527        buffer: Entity<Buffer>,
 6528        cx: &mut Context<Self>,
 6529    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6530        let buffer_id = buffer.read(cx).remote_id();
 6531
 6532        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6533            let mut suitable_capabilities = None;
 6534            // Are we capable for proto request?
 6535            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6536                &buffer,
 6537                |capabilities| {
 6538                    if let Some(caps) = &capabilities.diagnostic_provider {
 6539                        suitable_capabilities = Some(caps.clone());
 6540                        true
 6541                    } else {
 6542                        false
 6543                    }
 6544                },
 6545                cx,
 6546            );
 6547            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6548            let Some(dynamic_caps) = suitable_capabilities else {
 6549                return Task::ready(Ok(None));
 6550            };
 6551            assert!(any_server_has_diagnostics_provider);
 6552
 6553            let request = GetDocumentDiagnostics {
 6554                previous_result_id: None,
 6555                dynamic_caps,
 6556            };
 6557            let request_task = client.request_lsp(
 6558                upstream_project_id,
 6559                None,
 6560                LSP_REQUEST_TIMEOUT,
 6561                cx.background_executor().clone(),
 6562                request.to_proto(upstream_project_id, buffer.read(cx)),
 6563            );
 6564            cx.background_spawn(async move {
 6565                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6566                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6567                // Do not attempt to further process the dummy responses here.
 6568                let _response = request_task.await?;
 6569                Ok(None)
 6570            })
 6571        } else {
 6572            let servers = buffer.update(cx, |buffer, cx| {
 6573                self.language_servers_for_local_buffer(buffer, cx)
 6574                    .map(|(_, server)| server.clone())
 6575                    .collect::<Vec<_>>()
 6576            });
 6577
 6578            let pull_diagnostics = servers
 6579                .into_iter()
 6580                .flat_map(|server| {
 6581                    let result = maybe!({
 6582                        let local = self.as_local()?;
 6583                        let server_id = server.server_id();
 6584                        let providers_with_identifiers = local
 6585                            .language_server_dynamic_registrations
 6586                            .get(&server_id)
 6587                            .into_iter()
 6588                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6589                            .collect::<Vec<_>>();
 6590                        Some(
 6591                            providers_with_identifiers
 6592                                .into_iter()
 6593                                .map(|dynamic_caps| {
 6594                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6595                                    self.request_lsp(
 6596                                        buffer.clone(),
 6597                                        LanguageServerToQuery::Other(server_id),
 6598                                        GetDocumentDiagnostics {
 6599                                            previous_result_id: result_id,
 6600                                            dynamic_caps,
 6601                                        },
 6602                                        cx,
 6603                                    )
 6604                                })
 6605                                .collect::<Vec<_>>(),
 6606                        )
 6607                    });
 6608
 6609                    result.unwrap_or_default()
 6610                })
 6611                .collect::<Vec<_>>();
 6612
 6613            cx.background_spawn(async move {
 6614                let mut responses = Vec::new();
 6615                for diagnostics in join_all(pull_diagnostics).await {
 6616                    responses.extend(diagnostics?);
 6617                }
 6618                Ok(Some(responses))
 6619            })
 6620        }
 6621    }
 6622
 6623    pub fn applicable_inlay_chunks(
 6624        &mut self,
 6625        buffer: &Entity<Buffer>,
 6626        ranges: &[Range<text::Anchor>],
 6627        cx: &mut Context<Self>,
 6628    ) -> Vec<Range<BufferRow>> {
 6629        self.latest_lsp_data(buffer, cx)
 6630            .inlay_hints
 6631            .applicable_chunks(ranges)
 6632            .map(|chunk| chunk.start..chunk.end)
 6633            .collect()
 6634    }
 6635
 6636    pub fn invalidate_inlay_hints<'a>(
 6637        &'a mut self,
 6638        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6639    ) {
 6640        for buffer_id in for_buffers {
 6641            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6642                lsp_data.inlay_hints.clear();
 6643            }
 6644        }
 6645    }
 6646
 6647    pub fn inlay_hints(
 6648        &mut self,
 6649        invalidate: InvalidationStrategy,
 6650        buffer: Entity<Buffer>,
 6651        ranges: Vec<Range<text::Anchor>>,
 6652        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6653        cx: &mut Context<Self>,
 6654    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6655        let buffer_snapshot = buffer.read(cx).snapshot();
 6656        let next_hint_id = self.next_hint_id.clone();
 6657        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6658        let mut lsp_refresh_requested = false;
 6659        let for_server = if let InvalidationStrategy::RefreshRequested {
 6660            server_id,
 6661            request_id,
 6662        } = invalidate
 6663        {
 6664            let invalidated = lsp_data
 6665                .inlay_hints
 6666                .invalidate_for_server_refresh(server_id, request_id);
 6667            lsp_refresh_requested = invalidated;
 6668            Some(server_id)
 6669        } else {
 6670            None
 6671        };
 6672        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6673        let known_chunks = known_chunks
 6674            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6675            .map(|(_, known_chunks)| known_chunks)
 6676            .unwrap_or_default();
 6677
 6678        let mut hint_fetch_tasks = Vec::new();
 6679        let mut cached_inlay_hints = None;
 6680        let mut ranges_to_query = None;
 6681        let applicable_chunks = existing_inlay_hints
 6682            .applicable_chunks(ranges.as_slice())
 6683            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6684            .collect::<Vec<_>>();
 6685        if applicable_chunks.is_empty() {
 6686            return HashMap::default();
 6687        }
 6688
 6689        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6690
 6691        for row_chunk in applicable_chunks {
 6692            match (
 6693                existing_inlay_hints
 6694                    .cached_hints(&row_chunk)
 6695                    .filter(|_| !lsp_refresh_requested)
 6696                    .cloned(),
 6697                existing_inlay_hints
 6698                    .fetched_hints(&row_chunk)
 6699                    .as_ref()
 6700                    .filter(|_| !lsp_refresh_requested)
 6701                    .cloned(),
 6702            ) {
 6703                (None, None) => {
 6704                    let end = if last_chunk_number == row_chunk.id {
 6705                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6706                    } else {
 6707                        Point::new(row_chunk.end, 0)
 6708                    };
 6709                    ranges_to_query.get_or_insert_with(Vec::new).push((
 6710                        row_chunk,
 6711                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6712                            ..buffer_snapshot.anchor_after(end),
 6713                    ));
 6714                }
 6715                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6716                (Some(cached_hints), None) => {
 6717                    for (server_id, cached_hints) in cached_hints {
 6718                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6719                            cached_inlay_hints
 6720                                .get_or_insert_with(HashMap::default)
 6721                                .entry(row_chunk.start..row_chunk.end)
 6722                                .or_insert_with(HashMap::default)
 6723                                .entry(server_id)
 6724                                .or_insert_with(Vec::new)
 6725                                .extend(cached_hints);
 6726                        }
 6727                    }
 6728                }
 6729                (Some(cached_hints), Some(fetched_hints)) => {
 6730                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6731                    for (server_id, cached_hints) in cached_hints {
 6732                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6733                            cached_inlay_hints
 6734                                .get_or_insert_with(HashMap::default)
 6735                                .entry(row_chunk.start..row_chunk.end)
 6736                                .or_insert_with(HashMap::default)
 6737                                .entry(server_id)
 6738                                .or_insert_with(Vec::new)
 6739                                .extend(cached_hints);
 6740                        }
 6741                    }
 6742                }
 6743            }
 6744        }
 6745
 6746        if hint_fetch_tasks.is_empty()
 6747            && ranges_to_query
 6748                .as_ref()
 6749                .is_none_or(|ranges| ranges.is_empty())
 6750            && let Some(cached_inlay_hints) = cached_inlay_hints
 6751        {
 6752            cached_inlay_hints
 6753                .into_iter()
 6754                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6755                .collect()
 6756        } else {
 6757            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6758                let next_hint_id = next_hint_id.clone();
 6759                let buffer = buffer.clone();
 6760                let new_inlay_hints = cx
 6761                    .spawn(async move |lsp_store, cx| {
 6762                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6763                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6764                        })?;
 6765                        new_fetch_task
 6766                            .await
 6767                            .and_then(|new_hints_by_server| {
 6768                                lsp_store.update(cx, |lsp_store, cx| {
 6769                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6770                                    let update_cache = !lsp_data
 6771                                        .buffer_version
 6772                                        .changed_since(&buffer.read(cx).version());
 6773                                    if new_hints_by_server.is_empty() {
 6774                                        if update_cache {
 6775                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6776                                        }
 6777                                        HashMap::default()
 6778                                    } else {
 6779                                        new_hints_by_server
 6780                                            .into_iter()
 6781                                            .map(|(server_id, new_hints)| {
 6782                                                let new_hints = new_hints
 6783                                                    .into_iter()
 6784                                                    .map(|new_hint| {
 6785                                                        (
 6786                                                            InlayId::Hint(next_hint_id.fetch_add(
 6787                                                                1,
 6788                                                                atomic::Ordering::AcqRel,
 6789                                                            )),
 6790                                                            new_hint,
 6791                                                        )
 6792                                                    })
 6793                                                    .collect::<Vec<_>>();
 6794                                                if update_cache {
 6795                                                    lsp_data.inlay_hints.insert_new_hints(
 6796                                                        chunk,
 6797                                                        server_id,
 6798                                                        new_hints.clone(),
 6799                                                    );
 6800                                                }
 6801                                                (server_id, new_hints)
 6802                                            })
 6803                                            .collect()
 6804                                    }
 6805                                })
 6806                            })
 6807                            .map_err(Arc::new)
 6808                    })
 6809                    .shared();
 6810
 6811                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6812                *fetch_task = Some(new_inlay_hints.clone());
 6813                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6814            }
 6815
 6816            cached_inlay_hints
 6817                .unwrap_or_default()
 6818                .into_iter()
 6819                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6820                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6821                    (
 6822                        chunk.start..chunk.end,
 6823                        cx.spawn(async move |_, _| {
 6824                            hints_fetch.await.map_err(|e| {
 6825                                if e.error_code() != ErrorCode::Internal {
 6826                                    anyhow!(e.error_code())
 6827                                } else {
 6828                                    anyhow!("{e:#}")
 6829                                }
 6830                            })
 6831                        }),
 6832                    )
 6833                }))
 6834                .collect()
 6835        }
 6836    }
 6837
 6838    fn fetch_inlay_hints(
 6839        &mut self,
 6840        for_server: Option<LanguageServerId>,
 6841        buffer: &Entity<Buffer>,
 6842        range: Range<Anchor>,
 6843        cx: &mut Context<Self>,
 6844    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6845        let request = InlayHints {
 6846            range: range.clone(),
 6847        };
 6848        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6849            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6850                return Task::ready(Ok(HashMap::default()));
 6851            }
 6852            let request_task = upstream_client.request_lsp(
 6853                project_id,
 6854                for_server.map(|id| id.to_proto()),
 6855                LSP_REQUEST_TIMEOUT,
 6856                cx.background_executor().clone(),
 6857                request.to_proto(project_id, buffer.read(cx)),
 6858            );
 6859            let buffer = buffer.clone();
 6860            cx.spawn(async move |weak_lsp_store, cx| {
 6861                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6862                    return Ok(HashMap::default());
 6863                };
 6864                let Some(responses) = request_task.await? else {
 6865                    return Ok(HashMap::default());
 6866                };
 6867
 6868                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6869                    let lsp_store = lsp_store.clone();
 6870                    let buffer = buffer.clone();
 6871                    let cx = cx.clone();
 6872                    let request = request.clone();
 6873                    async move {
 6874                        (
 6875                            LanguageServerId::from_proto(response.server_id),
 6876                            request
 6877                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6878                                .await,
 6879                        )
 6880                    }
 6881                }))
 6882                .await;
 6883
 6884                let mut has_errors = false;
 6885                let inlay_hints = inlay_hints
 6886                    .into_iter()
 6887                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6888                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6889                        Err(e) => {
 6890                            has_errors = true;
 6891                            log::error!("{e:#}");
 6892                            None
 6893                        }
 6894                    })
 6895                    .collect::<HashMap<_, _>>();
 6896                anyhow::ensure!(
 6897                    !has_errors || !inlay_hints.is_empty(),
 6898                    "Failed to fetch inlay hints"
 6899                );
 6900                Ok(inlay_hints)
 6901            })
 6902        } else {
 6903            let inlay_hints_task = match for_server {
 6904                Some(server_id) => {
 6905                    let server_task = self.request_lsp(
 6906                        buffer.clone(),
 6907                        LanguageServerToQuery::Other(server_id),
 6908                        request,
 6909                        cx,
 6910                    );
 6911                    cx.background_spawn(async move {
 6912                        let mut responses = Vec::new();
 6913                        match server_task.await {
 6914                            Ok(response) => responses.push((server_id, response)),
 6915                            // rust-analyzer likes to error with this when its still loading up
 6916                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 6917                            Err(e) => log::error!(
 6918                                "Error handling response for inlay hints request: {e:#}"
 6919                            ),
 6920                        }
 6921                        responses
 6922                    })
 6923                }
 6924                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6925            };
 6926            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6927            cx.background_spawn(async move {
 6928                Ok(inlay_hints_task
 6929                    .await
 6930                    .into_iter()
 6931                    .map(|(server_id, mut new_hints)| {
 6932                        new_hints.retain(|hint| {
 6933                            hint.position.is_valid(&buffer_snapshot)
 6934                                && range.start.is_valid(&buffer_snapshot)
 6935                                && range.end.is_valid(&buffer_snapshot)
 6936                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6937                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6938                        });
 6939                        (server_id, new_hints)
 6940                    })
 6941                    .collect())
 6942            })
 6943        }
 6944    }
 6945
 6946    pub fn pull_diagnostics_for_buffer(
 6947        &mut self,
 6948        buffer: Entity<Buffer>,
 6949        cx: &mut Context<Self>,
 6950    ) -> Task<anyhow::Result<()>> {
 6951        let diagnostics = self.pull_diagnostics(buffer, cx);
 6952        cx.spawn(async move |lsp_store, cx| {
 6953            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6954                return Ok(());
 6955            };
 6956            lsp_store.update(cx, |lsp_store, cx| {
 6957                if lsp_store.as_local().is_none() {
 6958                    return;
 6959                }
 6960
 6961                let mut unchanged_buffers = HashSet::default();
 6962                let mut changed_buffers = HashSet::default();
 6963                let server_diagnostics_updates = diagnostics
 6964                    .into_iter()
 6965                    .filter_map(|diagnostics_set| match diagnostics_set {
 6966                        LspPullDiagnostics::Response {
 6967                            server_id,
 6968                            uri,
 6969                            diagnostics,
 6970                        } => Some((server_id, uri, diagnostics)),
 6971                        LspPullDiagnostics::Default => None,
 6972                    })
 6973                    .fold(
 6974                        HashMap::default(),
 6975                        |mut acc, (server_id, uri, diagnostics)| {
 6976                            let (result_id, diagnostics) = match diagnostics {
 6977                                PulledDiagnostics::Unchanged { result_id } => {
 6978                                    unchanged_buffers.insert(uri.clone());
 6979                                    (Some(result_id), Vec::new())
 6980                                }
 6981                                PulledDiagnostics::Changed {
 6982                                    result_id,
 6983                                    diagnostics,
 6984                                } => {
 6985                                    changed_buffers.insert(uri.clone());
 6986                                    (result_id, diagnostics)
 6987                                }
 6988                            };
 6989                            let disk_based_sources = Cow::Owned(
 6990                                lsp_store
 6991                                    .language_server_adapter_for_id(server_id)
 6992                                    .as_ref()
 6993                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6994                                    .unwrap_or(&[])
 6995                                    .to_vec(),
 6996                            );
 6997                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6998                                DocumentDiagnosticsUpdate {
 6999                                    server_id,
 7000                                    diagnostics: lsp::PublishDiagnosticsParams {
 7001                                        uri,
 7002                                        diagnostics,
 7003                                        version: None,
 7004                                    },
 7005                                    result_id,
 7006                                    disk_based_sources,
 7007                                },
 7008                            );
 7009                            acc
 7010                        },
 7011                    );
 7012
 7013                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7014                    lsp_store
 7015                        .merge_lsp_diagnostics(
 7016                            DiagnosticSourceKind::Pulled,
 7017                            diagnostic_updates,
 7018                            |buffer, old_diagnostic, cx| {
 7019                                File::from_dyn(buffer.file())
 7020                                    .and_then(|file| {
 7021                                        let abs_path = file.as_local()?.abs_path(cx);
 7022                                        lsp::Uri::from_file_path(abs_path).ok()
 7023                                    })
 7024                                    .is_none_or(|buffer_uri| {
 7025                                        unchanged_buffers.contains(&buffer_uri)
 7026                                            || match old_diagnostic.source_kind {
 7027                                                DiagnosticSourceKind::Pulled => {
 7028                                                    !changed_buffers.contains(&buffer_uri)
 7029                                                }
 7030                                                DiagnosticSourceKind::Other
 7031                                                | DiagnosticSourceKind::Pushed => true,
 7032                                            }
 7033                                    })
 7034                            },
 7035                            cx,
 7036                        )
 7037                        .log_err();
 7038                }
 7039            })
 7040        })
 7041    }
 7042
 7043    pub fn document_colors(
 7044        &mut self,
 7045        known_cache_version: Option<usize>,
 7046        buffer: Entity<Buffer>,
 7047        cx: &mut Context<Self>,
 7048    ) -> Option<DocumentColorTask> {
 7049        let version_queried_for = buffer.read(cx).version();
 7050        let buffer_id = buffer.read(cx).remote_id();
 7051
 7052        let current_language_servers = self.as_local().map(|local| {
 7053            local
 7054                .buffers_opened_in_servers
 7055                .get(&buffer_id)
 7056                .cloned()
 7057                .unwrap_or_default()
 7058        });
 7059
 7060        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7061            if let Some(cached_colors) = &lsp_data.document_colors {
 7062                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7063                    let has_different_servers =
 7064                        current_language_servers.is_some_and(|current_language_servers| {
 7065                            current_language_servers
 7066                                != cached_colors.colors.keys().copied().collect()
 7067                        });
 7068                    if !has_different_servers {
 7069                        let cache_version = cached_colors.cache_version;
 7070                        if Some(cache_version) == known_cache_version {
 7071                            return None;
 7072                        } else {
 7073                            return Some(
 7074                                Task::ready(Ok(DocumentColors {
 7075                                    colors: cached_colors
 7076                                        .colors
 7077                                        .values()
 7078                                        .flatten()
 7079                                        .cloned()
 7080                                        .collect(),
 7081                                    cache_version: Some(cache_version),
 7082                                }))
 7083                                .shared(),
 7084                            );
 7085                        }
 7086                    }
 7087                }
 7088            }
 7089        }
 7090
 7091        let color_lsp_data = self
 7092            .latest_lsp_data(&buffer, cx)
 7093            .document_colors
 7094            .get_or_insert_default();
 7095        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7096            && !version_queried_for.changed_since(updating_for)
 7097        {
 7098            return Some(running_update.clone());
 7099        }
 7100        let buffer_version_queried_for = version_queried_for.clone();
 7101        let new_task = cx
 7102            .spawn(async move |lsp_store, cx| {
 7103                cx.background_executor()
 7104                    .timer(Duration::from_millis(30))
 7105                    .await;
 7106                let fetched_colors = lsp_store
 7107                    .update(cx, |lsp_store, cx| {
 7108                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7109                    })?
 7110                    .await
 7111                    .context("fetching document colors")
 7112                    .map_err(Arc::new);
 7113                let fetched_colors = match fetched_colors {
 7114                    Ok(fetched_colors) => {
 7115                        if Some(true)
 7116                            == buffer
 7117                                .update(cx, |buffer, _| {
 7118                                    buffer.version() != buffer_version_queried_for
 7119                                })
 7120                                .ok()
 7121                        {
 7122                            return Ok(DocumentColors::default());
 7123                        }
 7124                        fetched_colors
 7125                    }
 7126                    Err(e) => {
 7127                        lsp_store
 7128                            .update(cx, |lsp_store, _| {
 7129                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7130                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7131                                        document_colors.colors_update = None;
 7132                                    }
 7133                                }
 7134                            })
 7135                            .ok();
 7136                        return Err(e);
 7137                    }
 7138                };
 7139
 7140                lsp_store
 7141                    .update(cx, |lsp_store, cx| {
 7142                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7143                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7144
 7145                        if let Some(fetched_colors) = fetched_colors {
 7146                            if lsp_data.buffer_version == buffer_version_queried_for {
 7147                                lsp_colors.colors.extend(fetched_colors);
 7148                                lsp_colors.cache_version += 1;
 7149                            } else if !lsp_data
 7150                                .buffer_version
 7151                                .changed_since(&buffer_version_queried_for)
 7152                            {
 7153                                lsp_data.buffer_version = buffer_version_queried_for;
 7154                                lsp_colors.colors = fetched_colors;
 7155                                lsp_colors.cache_version += 1;
 7156                            }
 7157                        }
 7158                        lsp_colors.colors_update = None;
 7159                        let colors = lsp_colors
 7160                            .colors
 7161                            .values()
 7162                            .flatten()
 7163                            .cloned()
 7164                            .collect::<HashSet<_>>();
 7165                        DocumentColors {
 7166                            colors,
 7167                            cache_version: Some(lsp_colors.cache_version),
 7168                        }
 7169                    })
 7170                    .map_err(Arc::new)
 7171            })
 7172            .shared();
 7173        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7174        Some(new_task)
 7175    }
 7176
 7177    fn fetch_document_colors_for_buffer(
 7178        &mut self,
 7179        buffer: &Entity<Buffer>,
 7180        cx: &mut Context<Self>,
 7181    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7182        if let Some((client, project_id)) = self.upstream_client() {
 7183            let request = GetDocumentColor {};
 7184            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7185                return Task::ready(Ok(None));
 7186            }
 7187
 7188            let request_task = client.request_lsp(
 7189                project_id,
 7190                None,
 7191                LSP_REQUEST_TIMEOUT,
 7192                cx.background_executor().clone(),
 7193                request.to_proto(project_id, buffer.read(cx)),
 7194            );
 7195            let buffer = buffer.clone();
 7196            cx.spawn(async move |lsp_store, cx| {
 7197                let Some(lsp_store) = lsp_store.upgrade() else {
 7198                    return Ok(None);
 7199                };
 7200                let colors = join_all(
 7201                    request_task
 7202                        .await
 7203                        .log_err()
 7204                        .flatten()
 7205                        .map(|response| response.payload)
 7206                        .unwrap_or_default()
 7207                        .into_iter()
 7208                        .map(|color_response| {
 7209                            let response = request.response_from_proto(
 7210                                color_response.response,
 7211                                lsp_store.clone(),
 7212                                buffer.clone(),
 7213                                cx.clone(),
 7214                            );
 7215                            async move {
 7216                                (
 7217                                    LanguageServerId::from_proto(color_response.server_id),
 7218                                    response.await.log_err().unwrap_or_default(),
 7219                                )
 7220                            }
 7221                        }),
 7222                )
 7223                .await
 7224                .into_iter()
 7225                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7226                    acc.entry(server_id)
 7227                        .or_insert_with(HashSet::default)
 7228                        .extend(colors);
 7229                    acc
 7230                });
 7231                Ok(Some(colors))
 7232            })
 7233        } else {
 7234            let document_colors_task =
 7235                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7236            cx.background_spawn(async move {
 7237                Ok(Some(
 7238                    document_colors_task
 7239                        .await
 7240                        .into_iter()
 7241                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7242                            acc.entry(server_id)
 7243                                .or_insert_with(HashSet::default)
 7244                                .extend(colors);
 7245                            acc
 7246                        })
 7247                        .into_iter()
 7248                        .collect(),
 7249                ))
 7250            })
 7251        }
 7252    }
 7253
 7254    pub fn signature_help<T: ToPointUtf16>(
 7255        &mut self,
 7256        buffer: &Entity<Buffer>,
 7257        position: T,
 7258        cx: &mut Context<Self>,
 7259    ) -> Task<Option<Vec<SignatureHelp>>> {
 7260        let position = position.to_point_utf16(buffer.read(cx));
 7261
 7262        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7263            let request = GetSignatureHelp { position };
 7264            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7265                return Task::ready(None);
 7266            }
 7267            let request_task = client.request_lsp(
 7268                upstream_project_id,
 7269                None,
 7270                LSP_REQUEST_TIMEOUT,
 7271                cx.background_executor().clone(),
 7272                request.to_proto(upstream_project_id, buffer.read(cx)),
 7273            );
 7274            let buffer = buffer.clone();
 7275            cx.spawn(async move |weak_lsp_store, cx| {
 7276                let lsp_store = weak_lsp_store.upgrade()?;
 7277                let signatures = join_all(
 7278                    request_task
 7279                        .await
 7280                        .log_err()
 7281                        .flatten()
 7282                        .map(|response| response.payload)
 7283                        .unwrap_or_default()
 7284                        .into_iter()
 7285                        .map(|response| {
 7286                            let response = GetSignatureHelp { position }.response_from_proto(
 7287                                response.response,
 7288                                lsp_store.clone(),
 7289                                buffer.clone(),
 7290                                cx.clone(),
 7291                            );
 7292                            async move { response.await.log_err().flatten() }
 7293                        }),
 7294                )
 7295                .await
 7296                .into_iter()
 7297                .flatten()
 7298                .collect();
 7299                Some(signatures)
 7300            })
 7301        } else {
 7302            let all_actions_task = self.request_multiple_lsp_locally(
 7303                buffer,
 7304                Some(position),
 7305                GetSignatureHelp { position },
 7306                cx,
 7307            );
 7308            cx.background_spawn(async move {
 7309                Some(
 7310                    all_actions_task
 7311                        .await
 7312                        .into_iter()
 7313                        .flat_map(|(_, actions)| actions)
 7314                        .collect::<Vec<_>>(),
 7315                )
 7316            })
 7317        }
 7318    }
 7319
 7320    pub fn hover(
 7321        &mut self,
 7322        buffer: &Entity<Buffer>,
 7323        position: PointUtf16,
 7324        cx: &mut Context<Self>,
 7325    ) -> Task<Option<Vec<Hover>>> {
 7326        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7327            let request = GetHover { position };
 7328            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7329                return Task::ready(None);
 7330            }
 7331            let request_task = client.request_lsp(
 7332                upstream_project_id,
 7333                None,
 7334                LSP_REQUEST_TIMEOUT,
 7335                cx.background_executor().clone(),
 7336                request.to_proto(upstream_project_id, buffer.read(cx)),
 7337            );
 7338            let buffer = buffer.clone();
 7339            cx.spawn(async move |weak_lsp_store, cx| {
 7340                let lsp_store = weak_lsp_store.upgrade()?;
 7341                let hovers = join_all(
 7342                    request_task
 7343                        .await
 7344                        .log_err()
 7345                        .flatten()
 7346                        .map(|response| response.payload)
 7347                        .unwrap_or_default()
 7348                        .into_iter()
 7349                        .map(|response| {
 7350                            let response = GetHover { position }.response_from_proto(
 7351                                response.response,
 7352                                lsp_store.clone(),
 7353                                buffer.clone(),
 7354                                cx.clone(),
 7355                            );
 7356                            async move {
 7357                                response
 7358                                    .await
 7359                                    .log_err()
 7360                                    .flatten()
 7361                                    .and_then(remove_empty_hover_blocks)
 7362                            }
 7363                        }),
 7364                )
 7365                .await
 7366                .into_iter()
 7367                .flatten()
 7368                .collect();
 7369                Some(hovers)
 7370            })
 7371        } else {
 7372            let all_actions_task = self.request_multiple_lsp_locally(
 7373                buffer,
 7374                Some(position),
 7375                GetHover { position },
 7376                cx,
 7377            );
 7378            cx.background_spawn(async move {
 7379                Some(
 7380                    all_actions_task
 7381                        .await
 7382                        .into_iter()
 7383                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7384                        .collect::<Vec<Hover>>(),
 7385                )
 7386            })
 7387        }
 7388    }
 7389
 7390    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7391        let language_registry = self.languages.clone();
 7392
 7393        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7394            let request = upstream_client.request(proto::GetProjectSymbols {
 7395                project_id: *project_id,
 7396                query: query.to_string(),
 7397            });
 7398            cx.foreground_executor().spawn(async move {
 7399                let response = request.await?;
 7400                let mut symbols = Vec::new();
 7401                let core_symbols = response
 7402                    .symbols
 7403                    .into_iter()
 7404                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7405                    .collect::<Vec<_>>();
 7406                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7407                    .await;
 7408                Ok(symbols)
 7409            })
 7410        } else if let Some(local) = self.as_local() {
 7411            struct WorkspaceSymbolsResult {
 7412                server_id: LanguageServerId,
 7413                lsp_adapter: Arc<CachedLspAdapter>,
 7414                worktree: WeakEntity<Worktree>,
 7415                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7416            }
 7417
 7418            let mut requests = Vec::new();
 7419            let mut requested_servers = BTreeSet::new();
 7420            for (seed, state) in local.language_server_ids.iter() {
 7421                let Some(worktree_handle) = self
 7422                    .worktree_store
 7423                    .read(cx)
 7424                    .worktree_for_id(seed.worktree_id, cx)
 7425                else {
 7426                    continue;
 7427                };
 7428                let worktree = worktree_handle.read(cx);
 7429                if !worktree.is_visible() {
 7430                    continue;
 7431                }
 7432
 7433                if !requested_servers.insert(state.id) {
 7434                    continue;
 7435                }
 7436
 7437                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7438                    Some(LanguageServerState::Running {
 7439                        adapter, server, ..
 7440                    }) => (adapter.clone(), server),
 7441
 7442                    _ => continue,
 7443                };
 7444                let supports_workspace_symbol_request =
 7445                    match server.capabilities().workspace_symbol_provider {
 7446                        Some(OneOf::Left(supported)) => supported,
 7447                        Some(OneOf::Right(_)) => true,
 7448                        None => false,
 7449                    };
 7450                if !supports_workspace_symbol_request {
 7451                    continue;
 7452                }
 7453                let worktree_handle = worktree_handle.clone();
 7454                let server_id = server.server_id();
 7455                requests.push(
 7456                        server
 7457                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7458                                lsp::WorkspaceSymbolParams {
 7459                                    query: query.to_string(),
 7460                                    ..Default::default()
 7461                                },
 7462                            )
 7463                            .map(move |response| {
 7464                                let lsp_symbols = response.into_response()
 7465                                    .context("workspace symbols request")
 7466                                    .log_err()
 7467                                    .flatten()
 7468                                    .map(|symbol_response| match symbol_response {
 7469                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7470                                            flat_responses.into_iter().map(|lsp_symbol| {
 7471                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7472                                            }).collect::<Vec<_>>()
 7473                                        }
 7474                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7475                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7476                                                let location = match lsp_symbol.location {
 7477                                                    OneOf::Left(location) => location,
 7478                                                    OneOf::Right(_) => {
 7479                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7480                                                        return None
 7481                                                    }
 7482                                                };
 7483                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7484                                            }).collect::<Vec<_>>()
 7485                                        }
 7486                                    }).unwrap_or_default();
 7487
 7488                                WorkspaceSymbolsResult {
 7489                                    server_id,
 7490                                    lsp_adapter,
 7491                                    worktree: worktree_handle.downgrade(),
 7492                                    lsp_symbols,
 7493                                }
 7494                            }),
 7495                    );
 7496            }
 7497
 7498            cx.spawn(async move |this, cx| {
 7499                let responses = futures::future::join_all(requests).await;
 7500                let this = match this.upgrade() {
 7501                    Some(this) => this,
 7502                    None => return Ok(Vec::new()),
 7503                };
 7504
 7505                let mut symbols = Vec::new();
 7506                for result in responses {
 7507                    let core_symbols = this.update(cx, |this, cx| {
 7508                        result
 7509                            .lsp_symbols
 7510                            .into_iter()
 7511                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7512                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7513                                let source_worktree = result.worktree.upgrade()?;
 7514                                let source_worktree_id = source_worktree.read(cx).id();
 7515
 7516                                let path = if let Some((tree, rel_path)) =
 7517                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7518                                {
 7519                                    let worktree_id = tree.read(cx).id();
 7520                                    SymbolLocation::InProject(ProjectPath {
 7521                                        worktree_id,
 7522                                        path: rel_path,
 7523                                    })
 7524                                } else {
 7525                                    SymbolLocation::OutsideProject {
 7526                                        signature: this.symbol_signature(&abs_path),
 7527                                        abs_path: abs_path.into(),
 7528                                    }
 7529                                };
 7530
 7531                                Some(CoreSymbol {
 7532                                    source_language_server_id: result.server_id,
 7533                                    language_server_name: result.lsp_adapter.name.clone(),
 7534                                    source_worktree_id,
 7535                                    path,
 7536                                    kind: symbol_kind,
 7537                                    name: symbol_name,
 7538                                    range: range_from_lsp(symbol_location.range),
 7539                                })
 7540                            })
 7541                            .collect()
 7542                    })?;
 7543
 7544                    populate_labels_for_symbols(
 7545                        core_symbols,
 7546                        &language_registry,
 7547                        Some(result.lsp_adapter),
 7548                        &mut symbols,
 7549                    )
 7550                    .await;
 7551                }
 7552
 7553                Ok(symbols)
 7554            })
 7555        } else {
 7556            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7557        }
 7558    }
 7559
 7560    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7561        let mut summary = DiagnosticSummary::default();
 7562        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7563            summary.error_count += path_summary.error_count;
 7564            summary.warning_count += path_summary.warning_count;
 7565        }
 7566        summary
 7567    }
 7568
 7569    /// Returns the diagnostic summary for a specific project path.
 7570    pub fn diagnostic_summary_for_path(
 7571        &self,
 7572        project_path: &ProjectPath,
 7573        _: &App,
 7574    ) -> DiagnosticSummary {
 7575        if let Some(summaries) = self
 7576            .diagnostic_summaries
 7577            .get(&project_path.worktree_id)
 7578            .and_then(|map| map.get(&project_path.path))
 7579        {
 7580            let (error_count, warning_count) = summaries.iter().fold(
 7581                (0, 0),
 7582                |(error_count, warning_count), (_language_server_id, summary)| {
 7583                    (
 7584                        error_count + summary.error_count,
 7585                        warning_count + summary.warning_count,
 7586                    )
 7587                },
 7588            );
 7589
 7590            DiagnosticSummary {
 7591                error_count,
 7592                warning_count,
 7593            }
 7594        } else {
 7595            DiagnosticSummary::default()
 7596        }
 7597    }
 7598
 7599    pub fn diagnostic_summaries<'a>(
 7600        &'a self,
 7601        include_ignored: bool,
 7602        cx: &'a App,
 7603    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7604        self.worktree_store
 7605            .read(cx)
 7606            .visible_worktrees(cx)
 7607            .filter_map(|worktree| {
 7608                let worktree = worktree.read(cx);
 7609                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7610            })
 7611            .flat_map(move |(worktree, summaries)| {
 7612                let worktree_id = worktree.id();
 7613                summaries
 7614                    .iter()
 7615                    .filter(move |(path, _)| {
 7616                        include_ignored
 7617                            || worktree
 7618                                .entry_for_path(path.as_ref())
 7619                                .is_some_and(|entry| !entry.is_ignored)
 7620                    })
 7621                    .flat_map(move |(path, summaries)| {
 7622                        summaries.iter().map(move |(server_id, summary)| {
 7623                            (
 7624                                ProjectPath {
 7625                                    worktree_id,
 7626                                    path: path.clone(),
 7627                                },
 7628                                *server_id,
 7629                                *summary,
 7630                            )
 7631                        })
 7632                    })
 7633            })
 7634    }
 7635
 7636    pub fn on_buffer_edited(
 7637        &mut self,
 7638        buffer: Entity<Buffer>,
 7639        cx: &mut Context<Self>,
 7640    ) -> Option<()> {
 7641        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7642            Some(
 7643                self.as_local()?
 7644                    .language_servers_for_buffer(buffer, cx)
 7645                    .map(|i| i.1.clone())
 7646                    .collect(),
 7647            )
 7648        })?;
 7649
 7650        let buffer = buffer.read(cx);
 7651        let file = File::from_dyn(buffer.file())?;
 7652        let abs_path = file.as_local()?.abs_path(cx);
 7653        let uri = lsp::Uri::from_file_path(&abs_path)
 7654            .ok()
 7655            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7656            .log_err()?;
 7657        let next_snapshot = buffer.text_snapshot();
 7658        for language_server in language_servers {
 7659            let language_server = language_server.clone();
 7660
 7661            let buffer_snapshots = self
 7662                .as_local_mut()?
 7663                .buffer_snapshots
 7664                .get_mut(&buffer.remote_id())
 7665                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7666            let previous_snapshot = buffer_snapshots.last()?;
 7667
 7668            let build_incremental_change = || {
 7669                buffer
 7670                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7671                        previous_snapshot.snapshot.version(),
 7672                    )
 7673                    .map(|edit| {
 7674                        let edit_start = edit.new.start.0;
 7675                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7676                        let new_text = next_snapshot
 7677                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7678                            .collect();
 7679                        lsp::TextDocumentContentChangeEvent {
 7680                            range: Some(lsp::Range::new(
 7681                                point_to_lsp(edit_start),
 7682                                point_to_lsp(edit_end),
 7683                            )),
 7684                            range_length: None,
 7685                            text: new_text,
 7686                        }
 7687                    })
 7688                    .collect()
 7689            };
 7690
 7691            let document_sync_kind = language_server
 7692                .capabilities()
 7693                .text_document_sync
 7694                .as_ref()
 7695                .and_then(|sync| match sync {
 7696                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7697                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7698                });
 7699
 7700            let content_changes: Vec<_> = match document_sync_kind {
 7701                Some(lsp::TextDocumentSyncKind::FULL) => {
 7702                    vec![lsp::TextDocumentContentChangeEvent {
 7703                        range: None,
 7704                        range_length: None,
 7705                        text: next_snapshot.text(),
 7706                    }]
 7707                }
 7708                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7709                _ => {
 7710                    #[cfg(any(test, feature = "test-support"))]
 7711                    {
 7712                        build_incremental_change()
 7713                    }
 7714
 7715                    #[cfg(not(any(test, feature = "test-support")))]
 7716                    {
 7717                        continue;
 7718                    }
 7719                }
 7720            };
 7721
 7722            let next_version = previous_snapshot.version + 1;
 7723            buffer_snapshots.push(LspBufferSnapshot {
 7724                version: next_version,
 7725                snapshot: next_snapshot.clone(),
 7726            });
 7727
 7728            language_server
 7729                .notify::<lsp::notification::DidChangeTextDocument>(
 7730                    lsp::DidChangeTextDocumentParams {
 7731                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7732                            uri.clone(),
 7733                            next_version,
 7734                        ),
 7735                        content_changes,
 7736                    },
 7737                )
 7738                .ok();
 7739            self.pull_workspace_diagnostics(language_server.server_id());
 7740        }
 7741
 7742        None
 7743    }
 7744
 7745    pub fn on_buffer_saved(
 7746        &mut self,
 7747        buffer: Entity<Buffer>,
 7748        cx: &mut Context<Self>,
 7749    ) -> Option<()> {
 7750        let file = File::from_dyn(buffer.read(cx).file())?;
 7751        let worktree_id = file.worktree_id(cx);
 7752        let abs_path = file.as_local()?.abs_path(cx);
 7753        let text_document = lsp::TextDocumentIdentifier {
 7754            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7755        };
 7756        let local = self.as_local()?;
 7757
 7758        for server in local.language_servers_for_worktree(worktree_id) {
 7759            if let Some(include_text) = include_text(server.as_ref()) {
 7760                let text = if include_text {
 7761                    Some(buffer.read(cx).text())
 7762                } else {
 7763                    None
 7764                };
 7765                server
 7766                    .notify::<lsp::notification::DidSaveTextDocument>(
 7767                        lsp::DidSaveTextDocumentParams {
 7768                            text_document: text_document.clone(),
 7769                            text,
 7770                        },
 7771                    )
 7772                    .ok();
 7773            }
 7774        }
 7775
 7776        let language_servers = buffer.update(cx, |buffer, cx| {
 7777            local.language_server_ids_for_buffer(buffer, cx)
 7778        });
 7779        for language_server_id in language_servers {
 7780            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7781        }
 7782
 7783        None
 7784    }
 7785
 7786    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7787        maybe!(async move {
 7788            let mut refreshed_servers = HashSet::default();
 7789            let servers = lsp_store
 7790                .update(cx, |lsp_store, cx| {
 7791                    let local = lsp_store.as_local()?;
 7792
 7793                    let servers = local
 7794                        .language_server_ids
 7795                        .iter()
 7796                        .filter_map(|(seed, state)| {
 7797                            let worktree = lsp_store
 7798                                .worktree_store
 7799                                .read(cx)
 7800                                .worktree_for_id(seed.worktree_id, cx);
 7801                            let delegate: Arc<dyn LspAdapterDelegate> =
 7802                                worktree.map(|worktree| {
 7803                                    LocalLspAdapterDelegate::new(
 7804                                        local.languages.clone(),
 7805                                        &local.environment,
 7806                                        cx.weak_entity(),
 7807                                        &worktree,
 7808                                        local.http_client.clone(),
 7809                                        local.fs.clone(),
 7810                                        cx,
 7811                                    )
 7812                                })?;
 7813                            let server_id = state.id;
 7814
 7815                            let states = local.language_servers.get(&server_id)?;
 7816
 7817                            match states {
 7818                                LanguageServerState::Starting { .. } => None,
 7819                                LanguageServerState::Running {
 7820                                    adapter, server, ..
 7821                                } => {
 7822                                    let adapter = adapter.clone();
 7823                                    let server = server.clone();
 7824                                    refreshed_servers.insert(server.name());
 7825                                    let toolchain = seed.toolchain.clone();
 7826                                    Some(cx.spawn(async move |_, cx| {
 7827                                        let settings =
 7828                                            LocalLspStore::workspace_configuration_for_adapter(
 7829                                                adapter.adapter.clone(),
 7830                                                &delegate,
 7831                                                toolchain,
 7832                                                cx,
 7833                                            )
 7834                                            .await
 7835                                            .ok()?;
 7836                                        server
 7837                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7838                                                lsp::DidChangeConfigurationParams { settings },
 7839                                            )
 7840                                            .ok()?;
 7841                                        Some(())
 7842                                    }))
 7843                                }
 7844                            }
 7845                        })
 7846                        .collect::<Vec<_>>();
 7847
 7848                    Some(servers)
 7849                })
 7850                .ok()
 7851                .flatten()?;
 7852
 7853            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7854            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7855            // to stop and unregister its language server wrapper.
 7856            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7857            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7858            let _: Vec<Option<()>> = join_all(servers).await;
 7859
 7860            Some(())
 7861        })
 7862        .await;
 7863    }
 7864
 7865    fn maintain_workspace_config(
 7866        external_refresh_requests: watch::Receiver<()>,
 7867        cx: &mut Context<Self>,
 7868    ) -> Task<Result<()>> {
 7869        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7870        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7871
 7872        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7873            *settings_changed_tx.borrow_mut() = ();
 7874        });
 7875
 7876        let mut joint_future =
 7877            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7878        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7879        // - 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).
 7880        // - 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.
 7881        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7882        // - 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,
 7883        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7884        cx.spawn(async move |this, cx| {
 7885            while let Some(()) = joint_future.next().await {
 7886                this.update(cx, |this, cx| {
 7887                    this.refresh_server_tree(cx);
 7888                })
 7889                .ok();
 7890
 7891                Self::refresh_workspace_configurations(&this, cx).await;
 7892            }
 7893
 7894            drop(settings_observation);
 7895            anyhow::Ok(())
 7896        })
 7897    }
 7898
 7899    pub fn language_servers_for_local_buffer<'a>(
 7900        &'a self,
 7901        buffer: &Buffer,
 7902        cx: &mut App,
 7903    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7904        let local = self.as_local();
 7905        let language_server_ids = local
 7906            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7907            .unwrap_or_default();
 7908
 7909        language_server_ids
 7910            .into_iter()
 7911            .filter_map(
 7912                move |server_id| match local?.language_servers.get(&server_id)? {
 7913                    LanguageServerState::Running {
 7914                        adapter, server, ..
 7915                    } => Some((adapter, server)),
 7916                    _ => None,
 7917                },
 7918            )
 7919    }
 7920
 7921    pub fn language_server_for_local_buffer<'a>(
 7922        &'a self,
 7923        buffer: &'a Buffer,
 7924        server_id: LanguageServerId,
 7925        cx: &'a mut App,
 7926    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7927        self.as_local()?
 7928            .language_servers_for_buffer(buffer, cx)
 7929            .find(|(_, s)| s.server_id() == server_id)
 7930    }
 7931
 7932    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7933        self.diagnostic_summaries.remove(&id_to_remove);
 7934        if let Some(local) = self.as_local_mut() {
 7935            let to_remove = local.remove_worktree(id_to_remove, cx);
 7936            for server in to_remove {
 7937                self.language_server_statuses.remove(&server);
 7938            }
 7939        }
 7940    }
 7941
 7942    pub fn shared(
 7943        &mut self,
 7944        project_id: u64,
 7945        downstream_client: AnyProtoClient,
 7946        _: &mut Context<Self>,
 7947    ) {
 7948        self.downstream_client = Some((downstream_client.clone(), project_id));
 7949
 7950        for (server_id, status) in &self.language_server_statuses {
 7951            if let Some(server) = self.language_server_for_id(*server_id) {
 7952                downstream_client
 7953                    .send(proto::StartLanguageServer {
 7954                        project_id,
 7955                        server: Some(proto::LanguageServer {
 7956                            id: server_id.to_proto(),
 7957                            name: status.name.to_string(),
 7958                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7959                        }),
 7960                        capabilities: serde_json::to_string(&server.capabilities())
 7961                            .expect("serializing server LSP capabilities"),
 7962                    })
 7963                    .log_err();
 7964            }
 7965        }
 7966    }
 7967
 7968    pub fn disconnected_from_host(&mut self) {
 7969        self.downstream_client.take();
 7970    }
 7971
 7972    pub fn disconnected_from_ssh_remote(&mut self) {
 7973        if let LspStoreMode::Remote(RemoteLspStore {
 7974            upstream_client, ..
 7975        }) = &mut self.mode
 7976        {
 7977            upstream_client.take();
 7978        }
 7979    }
 7980
 7981    pub(crate) fn set_language_server_statuses_from_proto(
 7982        &mut self,
 7983        project: WeakEntity<Project>,
 7984        language_servers: Vec<proto::LanguageServer>,
 7985        server_capabilities: Vec<String>,
 7986        cx: &mut Context<Self>,
 7987    ) {
 7988        let lsp_logs = cx
 7989            .try_global::<GlobalLogStore>()
 7990            .map(|lsp_store| lsp_store.0.clone());
 7991
 7992        self.language_server_statuses = language_servers
 7993            .into_iter()
 7994            .zip(server_capabilities)
 7995            .map(|(server, server_capabilities)| {
 7996                let server_id = LanguageServerId(server.id as usize);
 7997                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7998                    self.lsp_server_capabilities
 7999                        .insert(server_id, server_capabilities);
 8000                }
 8001
 8002                let name = LanguageServerName::from_proto(server.name);
 8003                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8004
 8005                if let Some(lsp_logs) = &lsp_logs {
 8006                    lsp_logs.update(cx, |lsp_logs, cx| {
 8007                        lsp_logs.add_language_server(
 8008                            // Only remote clients get their language servers set from proto
 8009                            LanguageServerKind::Remote {
 8010                                project: project.clone(),
 8011                            },
 8012                            server_id,
 8013                            Some(name.clone()),
 8014                            worktree,
 8015                            None,
 8016                            cx,
 8017                        );
 8018                    });
 8019                }
 8020
 8021                (
 8022                    server_id,
 8023                    LanguageServerStatus {
 8024                        name,
 8025                        pending_work: Default::default(),
 8026                        has_pending_diagnostic_updates: false,
 8027                        progress_tokens: Default::default(),
 8028                        worktree,
 8029                    },
 8030                )
 8031            })
 8032            .collect();
 8033    }
 8034
 8035    #[cfg(test)]
 8036    pub fn update_diagnostic_entries(
 8037        &mut self,
 8038        server_id: LanguageServerId,
 8039        abs_path: PathBuf,
 8040        result_id: Option<String>,
 8041        version: Option<i32>,
 8042        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8043        cx: &mut Context<Self>,
 8044    ) -> anyhow::Result<()> {
 8045        self.merge_diagnostic_entries(
 8046            vec![DocumentDiagnosticsUpdate {
 8047                diagnostics: DocumentDiagnostics {
 8048                    diagnostics,
 8049                    document_abs_path: abs_path,
 8050                    version,
 8051                },
 8052                result_id,
 8053                server_id,
 8054                disk_based_sources: Cow::Borrowed(&[]),
 8055            }],
 8056            |_, _, _| false,
 8057            cx,
 8058        )?;
 8059        Ok(())
 8060    }
 8061
 8062    pub fn merge_diagnostic_entries<'a>(
 8063        &mut self,
 8064        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8065        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8066        cx: &mut Context<Self>,
 8067    ) -> anyhow::Result<()> {
 8068        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8069        let mut updated_diagnostics_paths = HashMap::default();
 8070        for mut update in diagnostic_updates {
 8071            let abs_path = &update.diagnostics.document_abs_path;
 8072            let server_id = update.server_id;
 8073            let Some((worktree, relative_path)) =
 8074                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8075            else {
 8076                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8077                return Ok(());
 8078            };
 8079
 8080            let worktree_id = worktree.read(cx).id();
 8081            let project_path = ProjectPath {
 8082                worktree_id,
 8083                path: relative_path,
 8084            };
 8085
 8086            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8087                let snapshot = buffer_handle.read(cx).snapshot();
 8088                let buffer = buffer_handle.read(cx);
 8089                let reused_diagnostics = buffer
 8090                    .buffer_diagnostics(Some(server_id))
 8091                    .iter()
 8092                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8093                    .map(|v| {
 8094                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8095                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8096                        DiagnosticEntry {
 8097                            range: start..end,
 8098                            diagnostic: v.diagnostic.clone(),
 8099                        }
 8100                    })
 8101                    .collect::<Vec<_>>();
 8102
 8103                self.as_local_mut()
 8104                    .context("cannot merge diagnostics on a remote LspStore")?
 8105                    .update_buffer_diagnostics(
 8106                        &buffer_handle,
 8107                        server_id,
 8108                        update.result_id,
 8109                        update.diagnostics.version,
 8110                        update.diagnostics.diagnostics.clone(),
 8111                        reused_diagnostics.clone(),
 8112                        cx,
 8113                    )?;
 8114
 8115                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8116            }
 8117
 8118            let updated = worktree.update(cx, |worktree, cx| {
 8119                self.update_worktree_diagnostics(
 8120                    worktree.id(),
 8121                    server_id,
 8122                    project_path.path.clone(),
 8123                    update.diagnostics.diagnostics,
 8124                    cx,
 8125                )
 8126            })?;
 8127            match updated {
 8128                ControlFlow::Continue(new_summary) => {
 8129                    if let Some((project_id, new_summary)) = new_summary {
 8130                        match &mut diagnostics_summary {
 8131                            Some(diagnostics_summary) => {
 8132                                diagnostics_summary
 8133                                    .more_summaries
 8134                                    .push(proto::DiagnosticSummary {
 8135                                        path: project_path.path.as_ref().to_proto(),
 8136                                        language_server_id: server_id.0 as u64,
 8137                                        error_count: new_summary.error_count,
 8138                                        warning_count: new_summary.warning_count,
 8139                                    })
 8140                            }
 8141                            None => {
 8142                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8143                                    project_id,
 8144                                    worktree_id: worktree_id.to_proto(),
 8145                                    summary: Some(proto::DiagnosticSummary {
 8146                                        path: project_path.path.as_ref().to_proto(),
 8147                                        language_server_id: server_id.0 as u64,
 8148                                        error_count: new_summary.error_count,
 8149                                        warning_count: new_summary.warning_count,
 8150                                    }),
 8151                                    more_summaries: Vec::new(),
 8152                                })
 8153                            }
 8154                        }
 8155                    }
 8156                    updated_diagnostics_paths
 8157                        .entry(server_id)
 8158                        .or_insert_with(Vec::new)
 8159                        .push(project_path);
 8160                }
 8161                ControlFlow::Break(()) => {}
 8162            }
 8163        }
 8164
 8165        if let Some((diagnostics_summary, (downstream_client, _))) =
 8166            diagnostics_summary.zip(self.downstream_client.as_ref())
 8167        {
 8168            downstream_client.send(diagnostics_summary).log_err();
 8169        }
 8170        for (server_id, paths) in updated_diagnostics_paths {
 8171            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8172        }
 8173        Ok(())
 8174    }
 8175
 8176    fn update_worktree_diagnostics(
 8177        &mut self,
 8178        worktree_id: WorktreeId,
 8179        server_id: LanguageServerId,
 8180        path_in_worktree: Arc<RelPath>,
 8181        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8182        _: &mut Context<Worktree>,
 8183    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8184        let local = match &mut self.mode {
 8185            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8186            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8187        };
 8188
 8189        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8190        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8191        let summaries_by_server_id = summaries_for_tree
 8192            .entry(path_in_worktree.clone())
 8193            .or_default();
 8194
 8195        let old_summary = summaries_by_server_id
 8196            .remove(&server_id)
 8197            .unwrap_or_default();
 8198
 8199        let new_summary = DiagnosticSummary::new(&diagnostics);
 8200        if new_summary.is_empty() {
 8201            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8202            {
 8203                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8204                    diagnostics_by_server_id.remove(ix);
 8205                }
 8206                if diagnostics_by_server_id.is_empty() {
 8207                    diagnostics_for_tree.remove(&path_in_worktree);
 8208                }
 8209            }
 8210        } else {
 8211            summaries_by_server_id.insert(server_id, new_summary);
 8212            let diagnostics_by_server_id = diagnostics_for_tree
 8213                .entry(path_in_worktree.clone())
 8214                .or_default();
 8215            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8216                Ok(ix) => {
 8217                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8218                }
 8219                Err(ix) => {
 8220                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8221                }
 8222            }
 8223        }
 8224
 8225        if !old_summary.is_empty() || !new_summary.is_empty() {
 8226            if let Some((_, project_id)) = &self.downstream_client {
 8227                Ok(ControlFlow::Continue(Some((
 8228                    *project_id,
 8229                    proto::DiagnosticSummary {
 8230                        path: path_in_worktree.to_proto(),
 8231                        language_server_id: server_id.0 as u64,
 8232                        error_count: new_summary.error_count as u32,
 8233                        warning_count: new_summary.warning_count as u32,
 8234                    },
 8235                ))))
 8236            } else {
 8237                Ok(ControlFlow::Continue(None))
 8238            }
 8239        } else {
 8240            Ok(ControlFlow::Break(()))
 8241        }
 8242    }
 8243
 8244    pub fn open_buffer_for_symbol(
 8245        &mut self,
 8246        symbol: &Symbol,
 8247        cx: &mut Context<Self>,
 8248    ) -> Task<Result<Entity<Buffer>>> {
 8249        if let Some((client, project_id)) = self.upstream_client() {
 8250            let request = client.request(proto::OpenBufferForSymbol {
 8251                project_id,
 8252                symbol: Some(Self::serialize_symbol(symbol)),
 8253            });
 8254            cx.spawn(async move |this, cx| {
 8255                let response = request.await?;
 8256                let buffer_id = BufferId::new(response.buffer_id)?;
 8257                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8258                    .await
 8259            })
 8260        } else if let Some(local) = self.as_local() {
 8261            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8262                seed.worktree_id == symbol.source_worktree_id
 8263                    && state.id == symbol.source_language_server_id
 8264                    && symbol.language_server_name == seed.name
 8265            });
 8266            if !is_valid {
 8267                return Task::ready(Err(anyhow!(
 8268                    "language server for worktree and language not found"
 8269                )));
 8270            };
 8271
 8272            let symbol_abs_path = match &symbol.path {
 8273                SymbolLocation::InProject(project_path) => self
 8274                    .worktree_store
 8275                    .read(cx)
 8276                    .absolutize(&project_path, cx)
 8277                    .context("no such worktree"),
 8278                SymbolLocation::OutsideProject {
 8279                    abs_path,
 8280                    signature: _,
 8281                } => Ok(abs_path.to_path_buf()),
 8282            };
 8283            let symbol_abs_path = match symbol_abs_path {
 8284                Ok(abs_path) => abs_path,
 8285                Err(err) => return Task::ready(Err(err)),
 8286            };
 8287            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8288                uri
 8289            } else {
 8290                return Task::ready(Err(anyhow!("invalid symbol path")));
 8291            };
 8292
 8293            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8294        } else {
 8295            Task::ready(Err(anyhow!("no upstream client or local store")))
 8296        }
 8297    }
 8298
 8299    pub(crate) fn open_local_buffer_via_lsp(
 8300        &mut self,
 8301        abs_path: lsp::Uri,
 8302        language_server_id: LanguageServerId,
 8303        cx: &mut Context<Self>,
 8304    ) -> Task<Result<Entity<Buffer>>> {
 8305        cx.spawn(async move |lsp_store, cx| {
 8306            // Escape percent-encoded string.
 8307            let current_scheme = abs_path.scheme().to_owned();
 8308            // Uri is immutable, so we can't modify the scheme
 8309
 8310            let abs_path = abs_path
 8311                .to_file_path()
 8312                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8313            let p = abs_path.clone();
 8314            let yarn_worktree = lsp_store
 8315                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8316                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8317                        cx.spawn(async move |this, cx| {
 8318                            let t = this
 8319                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8320                                .ok()?;
 8321                            t.await
 8322                        })
 8323                    }),
 8324                    None => Task::ready(None),
 8325                })?
 8326                .await;
 8327            let (worktree_root_target, known_relative_path) =
 8328                if let Some((zip_root, relative_path)) = yarn_worktree {
 8329                    (zip_root, Some(relative_path))
 8330                } else {
 8331                    (Arc::<Path>::from(abs_path.as_path()), None)
 8332                };
 8333            let (worktree, relative_path) = if let Some(result) =
 8334                lsp_store.update(cx, |lsp_store, cx| {
 8335                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8336                        worktree_store.find_worktree(&worktree_root_target, cx)
 8337                    })
 8338                })? {
 8339                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8340                (result.0, relative_path)
 8341            } else {
 8342                let worktree = lsp_store
 8343                    .update(cx, |lsp_store, cx| {
 8344                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8345                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8346                        })
 8347                    })?
 8348                    .await?;
 8349                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8350                    lsp_store
 8351                        .update(cx, |lsp_store, cx| {
 8352                            if let Some(local) = lsp_store.as_local_mut() {
 8353                                local.register_language_server_for_invisible_worktree(
 8354                                    &worktree,
 8355                                    language_server_id,
 8356                                    cx,
 8357                                )
 8358                            }
 8359                        })
 8360                        .ok();
 8361                }
 8362                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8363                let relative_path = if let Some(known_path) = known_relative_path {
 8364                    known_path
 8365                } else {
 8366                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8367                        .into_arc()
 8368                };
 8369                (worktree, relative_path)
 8370            };
 8371            let project_path = ProjectPath {
 8372                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8373                path: relative_path,
 8374            };
 8375            lsp_store
 8376                .update(cx, |lsp_store, cx| {
 8377                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8378                        buffer_store.open_buffer(project_path, cx)
 8379                    })
 8380                })?
 8381                .await
 8382        })
 8383    }
 8384
 8385    fn request_multiple_lsp_locally<P, R>(
 8386        &mut self,
 8387        buffer: &Entity<Buffer>,
 8388        position: Option<P>,
 8389        request: R,
 8390        cx: &mut Context<Self>,
 8391    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8392    where
 8393        P: ToOffset,
 8394        R: LspCommand + Clone,
 8395        <R::LspRequest as lsp::request::Request>::Result: Send,
 8396        <R::LspRequest as lsp::request::Request>::Params: Send,
 8397    {
 8398        let Some(local) = self.as_local() else {
 8399            return Task::ready(Vec::new());
 8400        };
 8401
 8402        let snapshot = buffer.read(cx).snapshot();
 8403        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8404
 8405        let server_ids = buffer.update(cx, |buffer, cx| {
 8406            local
 8407                .language_servers_for_buffer(buffer, cx)
 8408                .filter(|(adapter, _)| {
 8409                    scope
 8410                        .as_ref()
 8411                        .map(|scope| scope.language_allowed(&adapter.name))
 8412                        .unwrap_or(true)
 8413                })
 8414                .map(|(_, server)| server.server_id())
 8415                .filter(|server_id| {
 8416                    self.as_local().is_none_or(|local| {
 8417                        local
 8418                            .buffers_opened_in_servers
 8419                            .get(&snapshot.remote_id())
 8420                            .is_some_and(|servers| servers.contains(server_id))
 8421                    })
 8422                })
 8423                .collect::<Vec<_>>()
 8424        });
 8425
 8426        let mut response_results = server_ids
 8427            .into_iter()
 8428            .map(|server_id| {
 8429                let task = self.request_lsp(
 8430                    buffer.clone(),
 8431                    LanguageServerToQuery::Other(server_id),
 8432                    request.clone(),
 8433                    cx,
 8434                );
 8435                async move { (server_id, task.await) }
 8436            })
 8437            .collect::<FuturesUnordered<_>>();
 8438
 8439        cx.background_spawn(async move {
 8440            let mut responses = Vec::with_capacity(response_results.len());
 8441            while let Some((server_id, response_result)) = response_results.next().await {
 8442                match response_result {
 8443                    Ok(response) => responses.push((server_id, response)),
 8444                    // rust-analyzer likes to error with this when its still loading up
 8445                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8446                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8447                }
 8448            }
 8449            responses
 8450        })
 8451    }
 8452
 8453    async fn handle_lsp_command<T: LspCommand>(
 8454        this: Entity<Self>,
 8455        envelope: TypedEnvelope<T::ProtoRequest>,
 8456        mut cx: AsyncApp,
 8457    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8458    where
 8459        <T::LspRequest as lsp::request::Request>::Params: Send,
 8460        <T::LspRequest as lsp::request::Request>::Result: Send,
 8461    {
 8462        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8463        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8464        let buffer_handle = this.update(&mut cx, |this, cx| {
 8465            this.buffer_store.read(cx).get_existing(buffer_id)
 8466        })??;
 8467        let request = T::from_proto(
 8468            envelope.payload,
 8469            this.clone(),
 8470            buffer_handle.clone(),
 8471            cx.clone(),
 8472        )
 8473        .await?;
 8474        let response = this
 8475            .update(&mut cx, |this, cx| {
 8476                this.request_lsp(
 8477                    buffer_handle.clone(),
 8478                    LanguageServerToQuery::FirstCapable,
 8479                    request,
 8480                    cx,
 8481                )
 8482            })?
 8483            .await?;
 8484        this.update(&mut cx, |this, cx| {
 8485            Ok(T::response_to_proto(
 8486                response,
 8487                this,
 8488                sender_id,
 8489                &buffer_handle.read(cx).version(),
 8490                cx,
 8491            ))
 8492        })?
 8493    }
 8494
 8495    async fn handle_lsp_query(
 8496        lsp_store: Entity<Self>,
 8497        envelope: TypedEnvelope<proto::LspQuery>,
 8498        mut cx: AsyncApp,
 8499    ) -> Result<proto::Ack> {
 8500        use proto::lsp_query::Request;
 8501        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8502        let lsp_query = envelope.payload;
 8503        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8504        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8505        match lsp_query.request.context("invalid LSP query request")? {
 8506            Request::GetReferences(get_references) => {
 8507                let position = get_references.position.clone().and_then(deserialize_anchor);
 8508                Self::query_lsp_locally::<GetReferences>(
 8509                    lsp_store,
 8510                    server_id,
 8511                    sender_id,
 8512                    lsp_request_id,
 8513                    get_references,
 8514                    position,
 8515                    &mut cx,
 8516                )
 8517                .await?;
 8518            }
 8519            Request::GetDocumentColor(get_document_color) => {
 8520                Self::query_lsp_locally::<GetDocumentColor>(
 8521                    lsp_store,
 8522                    server_id,
 8523                    sender_id,
 8524                    lsp_request_id,
 8525                    get_document_color,
 8526                    None,
 8527                    &mut cx,
 8528                )
 8529                .await?;
 8530            }
 8531            Request::GetHover(get_hover) => {
 8532                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8533                Self::query_lsp_locally::<GetHover>(
 8534                    lsp_store,
 8535                    server_id,
 8536                    sender_id,
 8537                    lsp_request_id,
 8538                    get_hover,
 8539                    position,
 8540                    &mut cx,
 8541                )
 8542                .await?;
 8543            }
 8544            Request::GetCodeActions(get_code_actions) => {
 8545                Self::query_lsp_locally::<GetCodeActions>(
 8546                    lsp_store,
 8547                    server_id,
 8548                    sender_id,
 8549                    lsp_request_id,
 8550                    get_code_actions,
 8551                    None,
 8552                    &mut cx,
 8553                )
 8554                .await?;
 8555            }
 8556            Request::GetSignatureHelp(get_signature_help) => {
 8557                let position = get_signature_help
 8558                    .position
 8559                    .clone()
 8560                    .and_then(deserialize_anchor);
 8561                Self::query_lsp_locally::<GetSignatureHelp>(
 8562                    lsp_store,
 8563                    server_id,
 8564                    sender_id,
 8565                    lsp_request_id,
 8566                    get_signature_help,
 8567                    position,
 8568                    &mut cx,
 8569                )
 8570                .await?;
 8571            }
 8572            Request::GetCodeLens(get_code_lens) => {
 8573                Self::query_lsp_locally::<GetCodeLens>(
 8574                    lsp_store,
 8575                    server_id,
 8576                    sender_id,
 8577                    lsp_request_id,
 8578                    get_code_lens,
 8579                    None,
 8580                    &mut cx,
 8581                )
 8582                .await?;
 8583            }
 8584            Request::GetDefinition(get_definition) => {
 8585                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8586                Self::query_lsp_locally::<GetDefinitions>(
 8587                    lsp_store,
 8588                    server_id,
 8589                    sender_id,
 8590                    lsp_request_id,
 8591                    get_definition,
 8592                    position,
 8593                    &mut cx,
 8594                )
 8595                .await?;
 8596            }
 8597            Request::GetDeclaration(get_declaration) => {
 8598                let position = get_declaration
 8599                    .position
 8600                    .clone()
 8601                    .and_then(deserialize_anchor);
 8602                Self::query_lsp_locally::<GetDeclarations>(
 8603                    lsp_store,
 8604                    server_id,
 8605                    sender_id,
 8606                    lsp_request_id,
 8607                    get_declaration,
 8608                    position,
 8609                    &mut cx,
 8610                )
 8611                .await?;
 8612            }
 8613            Request::GetTypeDefinition(get_type_definition) => {
 8614                let position = get_type_definition
 8615                    .position
 8616                    .clone()
 8617                    .and_then(deserialize_anchor);
 8618                Self::query_lsp_locally::<GetTypeDefinitions>(
 8619                    lsp_store,
 8620                    server_id,
 8621                    sender_id,
 8622                    lsp_request_id,
 8623                    get_type_definition,
 8624                    position,
 8625                    &mut cx,
 8626                )
 8627                .await?;
 8628            }
 8629            Request::GetImplementation(get_implementation) => {
 8630                let position = get_implementation
 8631                    .position
 8632                    .clone()
 8633                    .and_then(deserialize_anchor);
 8634                Self::query_lsp_locally::<GetImplementations>(
 8635                    lsp_store,
 8636                    server_id,
 8637                    sender_id,
 8638                    lsp_request_id,
 8639                    get_implementation,
 8640                    position,
 8641                    &mut cx,
 8642                )
 8643                .await?;
 8644            }
 8645            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8646                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8647                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8648                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8649                    this.buffer_store.read(cx).get_existing(buffer_id)
 8650                })??;
 8651                buffer
 8652                    .update(&mut cx, |buffer, _| {
 8653                        buffer.wait_for_version(version.clone())
 8654                    })?
 8655                    .await?;
 8656                lsp_store.update(&mut cx, |lsp_store, cx| {
 8657                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8658                    let key = LspKey {
 8659                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8660                        server_queried: server_id,
 8661                    };
 8662                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8663                    ) {
 8664                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8665                            lsp_requests.clear();
 8666                        };
 8667                    }
 8668
 8669                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8670                    existing_queries.insert(
 8671                        lsp_request_id,
 8672                        cx.spawn(async move |lsp_store, cx| {
 8673                            let diagnostics_pull = lsp_store
 8674                                .update(cx, |lsp_store, cx| {
 8675                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8676                                })
 8677                                .ok();
 8678                            if let Some(diagnostics_pull) = diagnostics_pull {
 8679                                match diagnostics_pull.await {
 8680                                    Ok(()) => {}
 8681                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8682                                };
 8683                            }
 8684                        }),
 8685                    );
 8686                })?;
 8687            }
 8688            Request::InlayHints(inlay_hints) => {
 8689                let query_start = inlay_hints
 8690                    .start
 8691                    .clone()
 8692                    .and_then(deserialize_anchor)
 8693                    .context("invalid inlay hints range start")?;
 8694                let query_end = inlay_hints
 8695                    .end
 8696                    .clone()
 8697                    .and_then(deserialize_anchor)
 8698                    .context("invalid inlay hints range end")?;
 8699                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8700                    &lsp_store,
 8701                    server_id,
 8702                    lsp_request_id,
 8703                    &inlay_hints,
 8704                    query_start..query_end,
 8705                    &mut cx,
 8706                )
 8707                .await
 8708                .context("preparing inlay hints request")?;
 8709                Self::query_lsp_locally::<InlayHints>(
 8710                    lsp_store,
 8711                    server_id,
 8712                    sender_id,
 8713                    lsp_request_id,
 8714                    inlay_hints,
 8715                    None,
 8716                    &mut cx,
 8717                )
 8718                .await
 8719                .context("querying for inlay hints")?
 8720            }
 8721        }
 8722        Ok(proto::Ack {})
 8723    }
 8724
 8725    async fn handle_lsp_query_response(
 8726        lsp_store: Entity<Self>,
 8727        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8728        cx: AsyncApp,
 8729    ) -> Result<()> {
 8730        lsp_store.read_with(&cx, |lsp_store, _| {
 8731            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8732                upstream_client.handle_lsp_response(envelope.clone());
 8733            }
 8734        })?;
 8735        Ok(())
 8736    }
 8737
 8738    async fn handle_apply_code_action(
 8739        this: Entity<Self>,
 8740        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8741        mut cx: AsyncApp,
 8742    ) -> Result<proto::ApplyCodeActionResponse> {
 8743        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8744        let action =
 8745            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8746        let apply_code_action = this.update(&mut cx, |this, cx| {
 8747            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8748            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8749            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8750        })??;
 8751
 8752        let project_transaction = apply_code_action.await?;
 8753        let project_transaction = this.update(&mut cx, |this, cx| {
 8754            this.buffer_store.update(cx, |buffer_store, cx| {
 8755                buffer_store.serialize_project_transaction_for_peer(
 8756                    project_transaction,
 8757                    sender_id,
 8758                    cx,
 8759                )
 8760            })
 8761        })?;
 8762        Ok(proto::ApplyCodeActionResponse {
 8763            transaction: Some(project_transaction),
 8764        })
 8765    }
 8766
 8767    async fn handle_register_buffer_with_language_servers(
 8768        this: Entity<Self>,
 8769        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8770        mut cx: AsyncApp,
 8771    ) -> Result<proto::Ack> {
 8772        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8773        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8774        this.update(&mut cx, |this, cx| {
 8775            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8776                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8777                    project_id: upstream_project_id,
 8778                    buffer_id: buffer_id.to_proto(),
 8779                    only_servers: envelope.payload.only_servers,
 8780                });
 8781            }
 8782
 8783            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8784                anyhow::bail!("buffer is not open");
 8785            };
 8786
 8787            let handle = this.register_buffer_with_language_servers(
 8788                &buffer,
 8789                envelope
 8790                    .payload
 8791                    .only_servers
 8792                    .into_iter()
 8793                    .filter_map(|selector| {
 8794                        Some(match selector.selector? {
 8795                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8796                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8797                            }
 8798                            proto::language_server_selector::Selector::Name(name) => {
 8799                                LanguageServerSelector::Name(LanguageServerName(
 8800                                    SharedString::from(name),
 8801                                ))
 8802                            }
 8803                        })
 8804                    })
 8805                    .collect(),
 8806                false,
 8807                cx,
 8808            );
 8809            this.buffer_store().update(cx, |buffer_store, _| {
 8810                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8811            });
 8812
 8813            Ok(())
 8814        })??;
 8815        Ok(proto::Ack {})
 8816    }
 8817
 8818    async fn handle_rename_project_entry(
 8819        this: Entity<Self>,
 8820        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8821        mut cx: AsyncApp,
 8822    ) -> Result<proto::ProjectEntryResponse> {
 8823        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8824        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8825        let new_path =
 8826            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8827
 8828        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8829            .update(&mut cx, |this, cx| {
 8830                let (worktree, entry) = this
 8831                    .worktree_store
 8832                    .read(cx)
 8833                    .worktree_and_entry_for_id(entry_id, cx)?;
 8834                let new_worktree = this
 8835                    .worktree_store
 8836                    .read(cx)
 8837                    .worktree_for_id(new_worktree_id, cx)?;
 8838                Some((
 8839                    this.worktree_store.clone(),
 8840                    worktree,
 8841                    new_worktree,
 8842                    entry.clone(),
 8843                ))
 8844            })?
 8845            .context("worktree not found")?;
 8846        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8847            (worktree.absolutize(&old_entry.path), worktree.id())
 8848        })?;
 8849        let new_abs_path =
 8850            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8851
 8852        let _transaction = Self::will_rename_entry(
 8853            this.downgrade(),
 8854            old_worktree_id,
 8855            &old_abs_path,
 8856            &new_abs_path,
 8857            old_entry.is_dir(),
 8858            cx.clone(),
 8859        )
 8860        .await;
 8861        let response = WorktreeStore::handle_rename_project_entry(
 8862            worktree_store,
 8863            envelope.payload,
 8864            cx.clone(),
 8865        )
 8866        .await;
 8867        this.read_with(&cx, |this, _| {
 8868            this.did_rename_entry(
 8869                old_worktree_id,
 8870                &old_abs_path,
 8871                &new_abs_path,
 8872                old_entry.is_dir(),
 8873            );
 8874        })
 8875        .ok();
 8876        response
 8877    }
 8878
 8879    async fn handle_update_diagnostic_summary(
 8880        this: Entity<Self>,
 8881        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8882        mut cx: AsyncApp,
 8883    ) -> Result<()> {
 8884        this.update(&mut cx, |lsp_store, cx| {
 8885            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8886            let mut updated_diagnostics_paths = HashMap::default();
 8887            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8888            for message_summary in envelope
 8889                .payload
 8890                .summary
 8891                .into_iter()
 8892                .chain(envelope.payload.more_summaries)
 8893            {
 8894                let project_path = ProjectPath {
 8895                    worktree_id,
 8896                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8897                };
 8898                let path = project_path.path.clone();
 8899                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8900                let summary = DiagnosticSummary {
 8901                    error_count: message_summary.error_count as usize,
 8902                    warning_count: message_summary.warning_count as usize,
 8903                };
 8904
 8905                if summary.is_empty() {
 8906                    if let Some(worktree_summaries) =
 8907                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8908                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8909                    {
 8910                        summaries.remove(&server_id);
 8911                        if summaries.is_empty() {
 8912                            worktree_summaries.remove(&path);
 8913                        }
 8914                    }
 8915                } else {
 8916                    lsp_store
 8917                        .diagnostic_summaries
 8918                        .entry(worktree_id)
 8919                        .or_default()
 8920                        .entry(path)
 8921                        .or_default()
 8922                        .insert(server_id, summary);
 8923                }
 8924
 8925                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8926                    match &mut diagnostics_summary {
 8927                        Some(diagnostics_summary) => {
 8928                            diagnostics_summary
 8929                                .more_summaries
 8930                                .push(proto::DiagnosticSummary {
 8931                                    path: project_path.path.as_ref().to_proto(),
 8932                                    language_server_id: server_id.0 as u64,
 8933                                    error_count: summary.error_count as u32,
 8934                                    warning_count: summary.warning_count as u32,
 8935                                })
 8936                        }
 8937                        None => {
 8938                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8939                                project_id: *project_id,
 8940                                worktree_id: worktree_id.to_proto(),
 8941                                summary: Some(proto::DiagnosticSummary {
 8942                                    path: project_path.path.as_ref().to_proto(),
 8943                                    language_server_id: server_id.0 as u64,
 8944                                    error_count: summary.error_count as u32,
 8945                                    warning_count: summary.warning_count as u32,
 8946                                }),
 8947                                more_summaries: Vec::new(),
 8948                            })
 8949                        }
 8950                    }
 8951                }
 8952                updated_diagnostics_paths
 8953                    .entry(server_id)
 8954                    .or_insert_with(Vec::new)
 8955                    .push(project_path);
 8956            }
 8957
 8958            if let Some((diagnostics_summary, (downstream_client, _))) =
 8959                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8960            {
 8961                downstream_client.send(diagnostics_summary).log_err();
 8962            }
 8963            for (server_id, paths) in updated_diagnostics_paths {
 8964                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8965            }
 8966            Ok(())
 8967        })?
 8968    }
 8969
 8970    async fn handle_start_language_server(
 8971        lsp_store: Entity<Self>,
 8972        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8973        mut cx: AsyncApp,
 8974    ) -> Result<()> {
 8975        let server = envelope.payload.server.context("invalid server")?;
 8976        let server_capabilities =
 8977            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8978                .with_context(|| {
 8979                    format!(
 8980                        "incorrect server capabilities {}",
 8981                        envelope.payload.capabilities
 8982                    )
 8983                })?;
 8984        lsp_store.update(&mut cx, |lsp_store, cx| {
 8985            let server_id = LanguageServerId(server.id as usize);
 8986            let server_name = LanguageServerName::from_proto(server.name.clone());
 8987            lsp_store
 8988                .lsp_server_capabilities
 8989                .insert(server_id, server_capabilities);
 8990            lsp_store.language_server_statuses.insert(
 8991                server_id,
 8992                LanguageServerStatus {
 8993                    name: server_name.clone(),
 8994                    pending_work: Default::default(),
 8995                    has_pending_diagnostic_updates: false,
 8996                    progress_tokens: Default::default(),
 8997                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8998                },
 8999            );
 9000            cx.emit(LspStoreEvent::LanguageServerAdded(
 9001                server_id,
 9002                server_name,
 9003                server.worktree_id.map(WorktreeId::from_proto),
 9004            ));
 9005            cx.notify();
 9006        })?;
 9007        Ok(())
 9008    }
 9009
 9010    async fn handle_update_language_server(
 9011        lsp_store: Entity<Self>,
 9012        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9013        mut cx: AsyncApp,
 9014    ) -> Result<()> {
 9015        lsp_store.update(&mut cx, |lsp_store, cx| {
 9016            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9017
 9018            match envelope.payload.variant.context("invalid variant")? {
 9019                proto::update_language_server::Variant::WorkStart(payload) => {
 9020                    lsp_store.on_lsp_work_start(
 9021                        language_server_id,
 9022                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9023                            .context("invalid progress token value")?,
 9024                        LanguageServerProgress {
 9025                            title: payload.title,
 9026                            is_disk_based_diagnostics_progress: false,
 9027                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9028                            message: payload.message,
 9029                            percentage: payload.percentage.map(|p| p as usize),
 9030                            last_update_at: cx.background_executor().now(),
 9031                        },
 9032                        cx,
 9033                    );
 9034                }
 9035                proto::update_language_server::Variant::WorkProgress(payload) => {
 9036                    lsp_store.on_lsp_work_progress(
 9037                        language_server_id,
 9038                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9039                            .context("invalid progress token value")?,
 9040                        LanguageServerProgress {
 9041                            title: None,
 9042                            is_disk_based_diagnostics_progress: false,
 9043                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9044                            message: payload.message,
 9045                            percentage: payload.percentage.map(|p| p as usize),
 9046                            last_update_at: cx.background_executor().now(),
 9047                        },
 9048                        cx,
 9049                    );
 9050                }
 9051
 9052                proto::update_language_server::Variant::WorkEnd(payload) => {
 9053                    lsp_store.on_lsp_work_end(
 9054                        language_server_id,
 9055                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9056                            .context("invalid progress token value")?,
 9057                        cx,
 9058                    );
 9059                }
 9060
 9061                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9062                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9063                }
 9064
 9065                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9066                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9067                }
 9068
 9069                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9070                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9071                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9072                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9073                        language_server_id,
 9074                        name: envelope
 9075                            .payload
 9076                            .server_name
 9077                            .map(SharedString::new)
 9078                            .map(LanguageServerName),
 9079                        message: non_lsp,
 9080                    });
 9081                }
 9082            }
 9083
 9084            Ok(())
 9085        })?
 9086    }
 9087
 9088    async fn handle_language_server_log(
 9089        this: Entity<Self>,
 9090        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9091        mut cx: AsyncApp,
 9092    ) -> Result<()> {
 9093        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9094        let log_type = envelope
 9095            .payload
 9096            .log_type
 9097            .map(LanguageServerLogType::from_proto)
 9098            .context("invalid language server log type")?;
 9099
 9100        let message = envelope.payload.message;
 9101
 9102        this.update(&mut cx, |_, cx| {
 9103            cx.emit(LspStoreEvent::LanguageServerLog(
 9104                language_server_id,
 9105                log_type,
 9106                message,
 9107            ));
 9108        })
 9109    }
 9110
 9111    async fn handle_lsp_ext_cancel_flycheck(
 9112        lsp_store: Entity<Self>,
 9113        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9114        cx: AsyncApp,
 9115    ) -> Result<proto::Ack> {
 9116        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9117        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9118            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9119                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9120            } else {
 9121                None
 9122            }
 9123        })?;
 9124        if let Some(task) = task {
 9125            task.context("handling lsp ext cancel flycheck")?;
 9126        }
 9127
 9128        Ok(proto::Ack {})
 9129    }
 9130
 9131    async fn handle_lsp_ext_run_flycheck(
 9132        lsp_store: Entity<Self>,
 9133        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9134        mut cx: AsyncApp,
 9135    ) -> Result<proto::Ack> {
 9136        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9137        lsp_store.update(&mut cx, |lsp_store, cx| {
 9138            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9139                let text_document = if envelope.payload.current_file_only {
 9140                    let buffer_id = envelope
 9141                        .payload
 9142                        .buffer_id
 9143                        .map(|id| BufferId::new(id))
 9144                        .transpose()?;
 9145                    buffer_id
 9146                        .and_then(|buffer_id| {
 9147                            lsp_store
 9148                                .buffer_store()
 9149                                .read(cx)
 9150                                .get(buffer_id)
 9151                                .and_then(|buffer| {
 9152                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9153                                })
 9154                                .map(|path| make_text_document_identifier(&path))
 9155                        })
 9156                        .transpose()?
 9157                } else {
 9158                    None
 9159                };
 9160                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9161                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9162                )?;
 9163            }
 9164            anyhow::Ok(())
 9165        })??;
 9166
 9167        Ok(proto::Ack {})
 9168    }
 9169
 9170    async fn handle_lsp_ext_clear_flycheck(
 9171        lsp_store: Entity<Self>,
 9172        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9173        cx: AsyncApp,
 9174    ) -> Result<proto::Ack> {
 9175        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9176        lsp_store
 9177            .read_with(&cx, |lsp_store, _| {
 9178                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9179                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9180                } else {
 9181                    None
 9182                }
 9183            })
 9184            .context("handling lsp ext clear flycheck")?;
 9185
 9186        Ok(proto::Ack {})
 9187    }
 9188
 9189    pub fn disk_based_diagnostics_started(
 9190        &mut self,
 9191        language_server_id: LanguageServerId,
 9192        cx: &mut Context<Self>,
 9193    ) {
 9194        if let Some(language_server_status) =
 9195            self.language_server_statuses.get_mut(&language_server_id)
 9196        {
 9197            language_server_status.has_pending_diagnostic_updates = true;
 9198        }
 9199
 9200        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9201        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9202            language_server_id,
 9203            name: self
 9204                .language_server_adapter_for_id(language_server_id)
 9205                .map(|adapter| adapter.name()),
 9206            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9207                Default::default(),
 9208            ),
 9209        })
 9210    }
 9211
 9212    pub fn disk_based_diagnostics_finished(
 9213        &mut self,
 9214        language_server_id: LanguageServerId,
 9215        cx: &mut Context<Self>,
 9216    ) {
 9217        if let Some(language_server_status) =
 9218            self.language_server_statuses.get_mut(&language_server_id)
 9219        {
 9220            language_server_status.has_pending_diagnostic_updates = false;
 9221        }
 9222
 9223        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9224        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9225            language_server_id,
 9226            name: self
 9227                .language_server_adapter_for_id(language_server_id)
 9228                .map(|adapter| adapter.name()),
 9229            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9230                Default::default(),
 9231            ),
 9232        })
 9233    }
 9234
 9235    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9236    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9237    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9238    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9239    // the language server might take some time to publish diagnostics.
 9240    fn simulate_disk_based_diagnostics_events_if_needed(
 9241        &mut self,
 9242        language_server_id: LanguageServerId,
 9243        cx: &mut Context<Self>,
 9244    ) {
 9245        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9246
 9247        let Some(LanguageServerState::Running {
 9248            simulate_disk_based_diagnostics_completion,
 9249            adapter,
 9250            ..
 9251        }) = self
 9252            .as_local_mut()
 9253            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9254        else {
 9255            return;
 9256        };
 9257
 9258        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9259            return;
 9260        }
 9261
 9262        let prev_task =
 9263            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9264                cx.background_executor()
 9265                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9266                    .await;
 9267
 9268                this.update(cx, |this, cx| {
 9269                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9270
 9271                    if let Some(LanguageServerState::Running {
 9272                        simulate_disk_based_diagnostics_completion,
 9273                        ..
 9274                    }) = this.as_local_mut().and_then(|local_store| {
 9275                        local_store.language_servers.get_mut(&language_server_id)
 9276                    }) {
 9277                        *simulate_disk_based_diagnostics_completion = None;
 9278                    }
 9279                })
 9280                .ok();
 9281            }));
 9282
 9283        if prev_task.is_none() {
 9284            self.disk_based_diagnostics_started(language_server_id, cx);
 9285        }
 9286    }
 9287
 9288    pub fn language_server_statuses(
 9289        &self,
 9290    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9291        self.language_server_statuses
 9292            .iter()
 9293            .map(|(key, value)| (*key, value))
 9294    }
 9295
 9296    pub(super) fn did_rename_entry(
 9297        &self,
 9298        worktree_id: WorktreeId,
 9299        old_path: &Path,
 9300        new_path: &Path,
 9301        is_dir: bool,
 9302    ) {
 9303        maybe!({
 9304            let local_store = self.as_local()?;
 9305
 9306            let old_uri = lsp::Uri::from_file_path(old_path)
 9307                .ok()
 9308                .map(|uri| uri.to_string())?;
 9309            let new_uri = lsp::Uri::from_file_path(new_path)
 9310                .ok()
 9311                .map(|uri| uri.to_string())?;
 9312
 9313            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9314                let Some(filter) = local_store
 9315                    .language_server_paths_watched_for_rename
 9316                    .get(&language_server.server_id())
 9317                else {
 9318                    continue;
 9319                };
 9320
 9321                if filter.should_send_did_rename(&old_uri, is_dir) {
 9322                    language_server
 9323                        .notify::<DidRenameFiles>(RenameFilesParams {
 9324                            files: vec![FileRename {
 9325                                old_uri: old_uri.clone(),
 9326                                new_uri: new_uri.clone(),
 9327                            }],
 9328                        })
 9329                        .ok();
 9330                }
 9331            }
 9332            Some(())
 9333        });
 9334    }
 9335
 9336    pub(super) fn will_rename_entry(
 9337        this: WeakEntity<Self>,
 9338        worktree_id: WorktreeId,
 9339        old_path: &Path,
 9340        new_path: &Path,
 9341        is_dir: bool,
 9342        cx: AsyncApp,
 9343    ) -> Task<ProjectTransaction> {
 9344        let old_uri = lsp::Uri::from_file_path(old_path)
 9345            .ok()
 9346            .map(|uri| uri.to_string());
 9347        let new_uri = lsp::Uri::from_file_path(new_path)
 9348            .ok()
 9349            .map(|uri| uri.to_string());
 9350        cx.spawn(async move |cx| {
 9351            let mut tasks = vec![];
 9352            this.update(cx, |this, cx| {
 9353                let local_store = this.as_local()?;
 9354                let old_uri = old_uri?;
 9355                let new_uri = new_uri?;
 9356                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9357                    let Some(filter) = local_store
 9358                        .language_server_paths_watched_for_rename
 9359                        .get(&language_server.server_id())
 9360                    else {
 9361                        continue;
 9362                    };
 9363
 9364                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9365                        let apply_edit = cx.spawn({
 9366                            let old_uri = old_uri.clone();
 9367                            let new_uri = new_uri.clone();
 9368                            let language_server = language_server.clone();
 9369                            async move |this, cx| {
 9370                                let edit = language_server
 9371                                    .request::<WillRenameFiles>(RenameFilesParams {
 9372                                        files: vec![FileRename { old_uri, new_uri }],
 9373                                    })
 9374                                    .await
 9375                                    .into_response()
 9376                                    .context("will rename files")
 9377                                    .log_err()
 9378                                    .flatten()?;
 9379
 9380                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9381                                    this.upgrade()?,
 9382                                    edit,
 9383                                    false,
 9384                                    language_server.clone(),
 9385                                    cx,
 9386                                )
 9387                                .await
 9388                                .ok()?;
 9389                                Some(transaction)
 9390                            }
 9391                        });
 9392                        tasks.push(apply_edit);
 9393                    }
 9394                }
 9395                Some(())
 9396            })
 9397            .ok()
 9398            .flatten();
 9399            let mut merged_transaction = ProjectTransaction::default();
 9400            for task in tasks {
 9401                // Await on tasks sequentially so that the order of application of edits is deterministic
 9402                // (at least with regards to the order of registration of language servers)
 9403                if let Some(transaction) = task.await {
 9404                    for (buffer, buffer_transaction) in transaction.0 {
 9405                        merged_transaction.0.insert(buffer, buffer_transaction);
 9406                    }
 9407                }
 9408            }
 9409            merged_transaction
 9410        })
 9411    }
 9412
 9413    fn lsp_notify_abs_paths_changed(
 9414        &mut self,
 9415        server_id: LanguageServerId,
 9416        changes: Vec<PathEvent>,
 9417    ) {
 9418        maybe!({
 9419            let server = self.language_server_for_id(server_id)?;
 9420            let changes = changes
 9421                .into_iter()
 9422                .filter_map(|event| {
 9423                    let typ = match event.kind? {
 9424                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9425                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9426                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9427                    };
 9428                    Some(lsp::FileEvent {
 9429                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9430                        typ,
 9431                    })
 9432                })
 9433                .collect::<Vec<_>>();
 9434            if !changes.is_empty() {
 9435                server
 9436                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9437                        lsp::DidChangeWatchedFilesParams { changes },
 9438                    )
 9439                    .ok();
 9440            }
 9441            Some(())
 9442        });
 9443    }
 9444
 9445    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9446        self.as_local()?.language_server_for_id(id)
 9447    }
 9448
 9449    fn on_lsp_progress(
 9450        &mut self,
 9451        progress_params: lsp::ProgressParams,
 9452        language_server_id: LanguageServerId,
 9453        disk_based_diagnostics_progress_token: Option<String>,
 9454        cx: &mut Context<Self>,
 9455    ) {
 9456        match progress_params.value {
 9457            lsp::ProgressParamsValue::WorkDone(progress) => {
 9458                self.handle_work_done_progress(
 9459                    progress,
 9460                    language_server_id,
 9461                    disk_based_diagnostics_progress_token,
 9462                    ProgressToken::from_lsp(progress_params.token),
 9463                    cx,
 9464                );
 9465            }
 9466            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9467                let identifier = match progress_params.token {
 9468                    lsp::NumberOrString::Number(_) => None,
 9469                    lsp::NumberOrString::String(token) => token
 9470                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9471                        .map(|(_, id)| id.to_owned()),
 9472                };
 9473                if let Some(LanguageServerState::Running {
 9474                    workspace_diagnostics_refresh_tasks,
 9475                    ..
 9476                }) = self
 9477                    .as_local_mut()
 9478                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9479                    && let Some(workspace_diagnostics) =
 9480                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9481                {
 9482                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9483                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9484                }
 9485            }
 9486        }
 9487    }
 9488
 9489    fn handle_work_done_progress(
 9490        &mut self,
 9491        progress: lsp::WorkDoneProgress,
 9492        language_server_id: LanguageServerId,
 9493        disk_based_diagnostics_progress_token: Option<String>,
 9494        token: ProgressToken,
 9495        cx: &mut Context<Self>,
 9496    ) {
 9497        let language_server_status =
 9498            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9499                status
 9500            } else {
 9501                return;
 9502            };
 9503
 9504        if !language_server_status.progress_tokens.contains(&token) {
 9505            return;
 9506        }
 9507
 9508        let is_disk_based_diagnostics_progress =
 9509            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9510                (&disk_based_diagnostics_progress_token, &token)
 9511            {
 9512                token.starts_with(disk_based_token)
 9513            } else {
 9514                false
 9515            };
 9516
 9517        match progress {
 9518            lsp::WorkDoneProgress::Begin(report) => {
 9519                if is_disk_based_diagnostics_progress {
 9520                    self.disk_based_diagnostics_started(language_server_id, cx);
 9521                }
 9522                self.on_lsp_work_start(
 9523                    language_server_id,
 9524                    token.clone(),
 9525                    LanguageServerProgress {
 9526                        title: Some(report.title),
 9527                        is_disk_based_diagnostics_progress,
 9528                        is_cancellable: report.cancellable.unwrap_or(false),
 9529                        message: report.message.clone(),
 9530                        percentage: report.percentage.map(|p| p as usize),
 9531                        last_update_at: cx.background_executor().now(),
 9532                    },
 9533                    cx,
 9534                );
 9535            }
 9536            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9537                language_server_id,
 9538                token,
 9539                LanguageServerProgress {
 9540                    title: None,
 9541                    is_disk_based_diagnostics_progress,
 9542                    is_cancellable: report.cancellable.unwrap_or(false),
 9543                    message: report.message,
 9544                    percentage: report.percentage.map(|p| p as usize),
 9545                    last_update_at: cx.background_executor().now(),
 9546                },
 9547                cx,
 9548            ),
 9549            lsp::WorkDoneProgress::End(_) => {
 9550                language_server_status.progress_tokens.remove(&token);
 9551                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9552                if is_disk_based_diagnostics_progress {
 9553                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9554                }
 9555            }
 9556        }
 9557    }
 9558
 9559    fn on_lsp_work_start(
 9560        &mut self,
 9561        language_server_id: LanguageServerId,
 9562        token: ProgressToken,
 9563        progress: LanguageServerProgress,
 9564        cx: &mut Context<Self>,
 9565    ) {
 9566        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9567            status.pending_work.insert(token.clone(), progress.clone());
 9568            cx.notify();
 9569        }
 9570        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9571            language_server_id,
 9572            name: self
 9573                .language_server_adapter_for_id(language_server_id)
 9574                .map(|adapter| adapter.name()),
 9575            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9576                token: Some(token.to_proto()),
 9577                title: progress.title,
 9578                message: progress.message,
 9579                percentage: progress.percentage.map(|p| p as u32),
 9580                is_cancellable: Some(progress.is_cancellable),
 9581            }),
 9582        })
 9583    }
 9584
 9585    fn on_lsp_work_progress(
 9586        &mut self,
 9587        language_server_id: LanguageServerId,
 9588        token: ProgressToken,
 9589        progress: LanguageServerProgress,
 9590        cx: &mut Context<Self>,
 9591    ) {
 9592        let mut did_update = false;
 9593        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9594            match status.pending_work.entry(token.clone()) {
 9595                btree_map::Entry::Vacant(entry) => {
 9596                    entry.insert(progress.clone());
 9597                    did_update = true;
 9598                }
 9599                btree_map::Entry::Occupied(mut entry) => {
 9600                    let entry = entry.get_mut();
 9601                    if (progress.last_update_at - entry.last_update_at)
 9602                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9603                    {
 9604                        entry.last_update_at = progress.last_update_at;
 9605                        if progress.message.is_some() {
 9606                            entry.message = progress.message.clone();
 9607                        }
 9608                        if progress.percentage.is_some() {
 9609                            entry.percentage = progress.percentage;
 9610                        }
 9611                        if progress.is_cancellable != entry.is_cancellable {
 9612                            entry.is_cancellable = progress.is_cancellable;
 9613                        }
 9614                        did_update = true;
 9615                    }
 9616                }
 9617            }
 9618        }
 9619
 9620        if did_update {
 9621            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9622                language_server_id,
 9623                name: self
 9624                    .language_server_adapter_for_id(language_server_id)
 9625                    .map(|adapter| adapter.name()),
 9626                message: proto::update_language_server::Variant::WorkProgress(
 9627                    proto::LspWorkProgress {
 9628                        token: Some(token.to_proto()),
 9629                        message: progress.message,
 9630                        percentage: progress.percentage.map(|p| p as u32),
 9631                        is_cancellable: Some(progress.is_cancellable),
 9632                    },
 9633                ),
 9634            })
 9635        }
 9636    }
 9637
 9638    fn on_lsp_work_end(
 9639        &mut self,
 9640        language_server_id: LanguageServerId,
 9641        token: ProgressToken,
 9642        cx: &mut Context<Self>,
 9643    ) {
 9644        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9645            if let Some(work) = status.pending_work.remove(&token)
 9646                && !work.is_disk_based_diagnostics_progress
 9647            {
 9648                cx.emit(LspStoreEvent::RefreshInlayHints {
 9649                    server_id: language_server_id,
 9650                    request_id: None,
 9651                });
 9652            }
 9653            cx.notify();
 9654        }
 9655
 9656        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9657            language_server_id,
 9658            name: self
 9659                .language_server_adapter_for_id(language_server_id)
 9660                .map(|adapter| adapter.name()),
 9661            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9662                token: Some(token.to_proto()),
 9663            }),
 9664        })
 9665    }
 9666
 9667    pub async fn handle_resolve_completion_documentation(
 9668        this: Entity<Self>,
 9669        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9670        mut cx: AsyncApp,
 9671    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9672        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9673
 9674        let completion = this
 9675            .read_with(&cx, |this, cx| {
 9676                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9677                let server = this
 9678                    .language_server_for_id(id)
 9679                    .with_context(|| format!("No language server {id}"))?;
 9680
 9681                anyhow::Ok(cx.background_spawn(async move {
 9682                    let can_resolve = server
 9683                        .capabilities()
 9684                        .completion_provider
 9685                        .as_ref()
 9686                        .and_then(|options| options.resolve_provider)
 9687                        .unwrap_or(false);
 9688                    if can_resolve {
 9689                        server
 9690                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9691                            .await
 9692                            .into_response()
 9693                            .context("resolve completion item")
 9694                    } else {
 9695                        anyhow::Ok(lsp_completion)
 9696                    }
 9697                }))
 9698            })??
 9699            .await?;
 9700
 9701        let mut documentation_is_markdown = false;
 9702        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9703        let documentation = match completion.documentation {
 9704            Some(lsp::Documentation::String(text)) => text,
 9705
 9706            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9707                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9708                value
 9709            }
 9710
 9711            _ => String::new(),
 9712        };
 9713
 9714        // If we have a new buffer_id, that means we're talking to a new client
 9715        // and want to check for new text_edits in the completion too.
 9716        let mut old_replace_start = None;
 9717        let mut old_replace_end = None;
 9718        let mut old_insert_start = None;
 9719        let mut old_insert_end = None;
 9720        let mut new_text = String::default();
 9721        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9722            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9723                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9724                anyhow::Ok(buffer.read(cx).snapshot())
 9725            })??;
 9726
 9727            if let Some(text_edit) = completion.text_edit.as_ref() {
 9728                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9729
 9730                if let Some(mut edit) = edit {
 9731                    LineEnding::normalize(&mut edit.new_text);
 9732
 9733                    new_text = edit.new_text;
 9734                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9735                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9736                    if let Some(insert_range) = edit.insert_range {
 9737                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9738                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9739                    }
 9740                }
 9741            }
 9742        }
 9743
 9744        Ok(proto::ResolveCompletionDocumentationResponse {
 9745            documentation,
 9746            documentation_is_markdown,
 9747            old_replace_start,
 9748            old_replace_end,
 9749            new_text,
 9750            lsp_completion,
 9751            old_insert_start,
 9752            old_insert_end,
 9753        })
 9754    }
 9755
 9756    async fn handle_on_type_formatting(
 9757        this: Entity<Self>,
 9758        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9759        mut cx: AsyncApp,
 9760    ) -> Result<proto::OnTypeFormattingResponse> {
 9761        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9762            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9763            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9764            let position = envelope
 9765                .payload
 9766                .position
 9767                .and_then(deserialize_anchor)
 9768                .context("invalid position")?;
 9769            anyhow::Ok(this.apply_on_type_formatting(
 9770                buffer,
 9771                position,
 9772                envelope.payload.trigger.clone(),
 9773                cx,
 9774            ))
 9775        })??;
 9776
 9777        let transaction = on_type_formatting
 9778            .await?
 9779            .as_ref()
 9780            .map(language::proto::serialize_transaction);
 9781        Ok(proto::OnTypeFormattingResponse { transaction })
 9782    }
 9783
 9784    async fn handle_refresh_inlay_hints(
 9785        lsp_store: Entity<Self>,
 9786        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9787        mut cx: AsyncApp,
 9788    ) -> Result<proto::Ack> {
 9789        lsp_store.update(&mut cx, |_, cx| {
 9790            cx.emit(LspStoreEvent::RefreshInlayHints {
 9791                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9792                request_id: envelope.payload.request_id.map(|id| id as usize),
 9793            });
 9794        })?;
 9795        Ok(proto::Ack {})
 9796    }
 9797
 9798    async fn handle_pull_workspace_diagnostics(
 9799        lsp_store: Entity<Self>,
 9800        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9801        mut cx: AsyncApp,
 9802    ) -> Result<proto::Ack> {
 9803        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9804        lsp_store.update(&mut cx, |lsp_store, _| {
 9805            lsp_store.pull_workspace_diagnostics(server_id);
 9806        })?;
 9807        Ok(proto::Ack {})
 9808    }
 9809
 9810    async fn handle_get_color_presentation(
 9811        lsp_store: Entity<Self>,
 9812        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9813        mut cx: AsyncApp,
 9814    ) -> Result<proto::GetColorPresentationResponse> {
 9815        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9816        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9817            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9818        })??;
 9819
 9820        let color = envelope
 9821            .payload
 9822            .color
 9823            .context("invalid color resolve request")?;
 9824        let start = color
 9825            .lsp_range_start
 9826            .context("invalid color resolve request")?;
 9827        let end = color
 9828            .lsp_range_end
 9829            .context("invalid color resolve request")?;
 9830
 9831        let color = DocumentColor {
 9832            lsp_range: lsp::Range {
 9833                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9834                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9835            },
 9836            color: lsp::Color {
 9837                red: color.red,
 9838                green: color.green,
 9839                blue: color.blue,
 9840                alpha: color.alpha,
 9841            },
 9842            resolved: false,
 9843            color_presentations: Vec::new(),
 9844        };
 9845        let resolved_color = lsp_store
 9846            .update(&mut cx, |lsp_store, cx| {
 9847                lsp_store.resolve_color_presentation(
 9848                    color,
 9849                    buffer.clone(),
 9850                    LanguageServerId(envelope.payload.server_id as usize),
 9851                    cx,
 9852                )
 9853            })?
 9854            .await
 9855            .context("resolving color presentation")?;
 9856
 9857        Ok(proto::GetColorPresentationResponse {
 9858            presentations: resolved_color
 9859                .color_presentations
 9860                .into_iter()
 9861                .map(|presentation| proto::ColorPresentation {
 9862                    label: presentation.label.to_string(),
 9863                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9864                    additional_text_edits: presentation
 9865                        .additional_text_edits
 9866                        .into_iter()
 9867                        .map(serialize_lsp_edit)
 9868                        .collect(),
 9869                })
 9870                .collect(),
 9871        })
 9872    }
 9873
 9874    async fn handle_resolve_inlay_hint(
 9875        lsp_store: Entity<Self>,
 9876        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9877        mut cx: AsyncApp,
 9878    ) -> Result<proto::ResolveInlayHintResponse> {
 9879        let proto_hint = envelope
 9880            .payload
 9881            .hint
 9882            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9883        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9884            .context("resolved proto inlay hint conversion")?;
 9885        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9886            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9887            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9888        })??;
 9889        let response_hint = lsp_store
 9890            .update(&mut cx, |lsp_store, cx| {
 9891                lsp_store.resolve_inlay_hint(
 9892                    hint,
 9893                    buffer,
 9894                    LanguageServerId(envelope.payload.language_server_id as usize),
 9895                    cx,
 9896                )
 9897            })?
 9898            .await
 9899            .context("inlay hints fetch")?;
 9900        Ok(proto::ResolveInlayHintResponse {
 9901            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9902        })
 9903    }
 9904
 9905    async fn handle_refresh_code_lens(
 9906        this: Entity<Self>,
 9907        _: TypedEnvelope<proto::RefreshCodeLens>,
 9908        mut cx: AsyncApp,
 9909    ) -> Result<proto::Ack> {
 9910        this.update(&mut cx, |_, cx| {
 9911            cx.emit(LspStoreEvent::RefreshCodeLens);
 9912        })?;
 9913        Ok(proto::Ack {})
 9914    }
 9915
 9916    async fn handle_open_buffer_for_symbol(
 9917        this: Entity<Self>,
 9918        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9919        mut cx: AsyncApp,
 9920    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9921        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9922        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9923        let symbol = Self::deserialize_symbol(symbol)?;
 9924        this.read_with(&cx, |this, _| {
 9925            if let SymbolLocation::OutsideProject {
 9926                abs_path,
 9927                signature,
 9928            } = &symbol.path
 9929            {
 9930                let new_signature = this.symbol_signature(&abs_path);
 9931                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9932            }
 9933            Ok(())
 9934        })??;
 9935        let buffer = this
 9936            .update(&mut cx, |this, cx| {
 9937                this.open_buffer_for_symbol(
 9938                    &Symbol {
 9939                        language_server_name: symbol.language_server_name,
 9940                        source_worktree_id: symbol.source_worktree_id,
 9941                        source_language_server_id: symbol.source_language_server_id,
 9942                        path: symbol.path,
 9943                        name: symbol.name,
 9944                        kind: symbol.kind,
 9945                        range: symbol.range,
 9946                        label: CodeLabel::default(),
 9947                    },
 9948                    cx,
 9949                )
 9950            })?
 9951            .await?;
 9952
 9953        this.update(&mut cx, |this, cx| {
 9954            let is_private = buffer
 9955                .read(cx)
 9956                .file()
 9957                .map(|f| f.is_private())
 9958                .unwrap_or_default();
 9959            if is_private {
 9960                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9961            } else {
 9962                this.buffer_store
 9963                    .update(cx, |buffer_store, cx| {
 9964                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9965                    })
 9966                    .detach_and_log_err(cx);
 9967                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9968                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9969            }
 9970        })?
 9971    }
 9972
 9973    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9974        let mut hasher = Sha256::new();
 9975        hasher.update(abs_path.to_string_lossy().as_bytes());
 9976        hasher.update(self.nonce.to_be_bytes());
 9977        hasher.finalize().as_slice().try_into().unwrap()
 9978    }
 9979
 9980    pub async fn handle_get_project_symbols(
 9981        this: Entity<Self>,
 9982        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9983        mut cx: AsyncApp,
 9984    ) -> Result<proto::GetProjectSymbolsResponse> {
 9985        let symbols = this
 9986            .update(&mut cx, |this, cx| {
 9987                this.symbols(&envelope.payload.query, cx)
 9988            })?
 9989            .await?;
 9990
 9991        Ok(proto::GetProjectSymbolsResponse {
 9992            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9993        })
 9994    }
 9995
 9996    pub async fn handle_restart_language_servers(
 9997        this: Entity<Self>,
 9998        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9999        mut cx: AsyncApp,
10000    ) -> Result<proto::Ack> {
10001        this.update(&mut cx, |lsp_store, cx| {
10002            let buffers =
10003                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10004            lsp_store.restart_language_servers_for_buffers(
10005                buffers,
10006                envelope
10007                    .payload
10008                    .only_servers
10009                    .into_iter()
10010                    .filter_map(|selector| {
10011                        Some(match selector.selector? {
10012                            proto::language_server_selector::Selector::ServerId(server_id) => {
10013                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10014                            }
10015                            proto::language_server_selector::Selector::Name(name) => {
10016                                LanguageServerSelector::Name(LanguageServerName(
10017                                    SharedString::from(name),
10018                                ))
10019                            }
10020                        })
10021                    })
10022                    .collect(),
10023                cx,
10024            );
10025        })?;
10026
10027        Ok(proto::Ack {})
10028    }
10029
10030    pub async fn handle_stop_language_servers(
10031        lsp_store: Entity<Self>,
10032        envelope: TypedEnvelope<proto::StopLanguageServers>,
10033        mut cx: AsyncApp,
10034    ) -> Result<proto::Ack> {
10035        lsp_store.update(&mut cx, |lsp_store, cx| {
10036            if envelope.payload.all
10037                && envelope.payload.also_servers.is_empty()
10038                && envelope.payload.buffer_ids.is_empty()
10039            {
10040                lsp_store.stop_all_language_servers(cx);
10041            } else {
10042                let buffers =
10043                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10044                lsp_store
10045                    .stop_language_servers_for_buffers(
10046                        buffers,
10047                        envelope
10048                            .payload
10049                            .also_servers
10050                            .into_iter()
10051                            .filter_map(|selector| {
10052                                Some(match selector.selector? {
10053                                    proto::language_server_selector::Selector::ServerId(
10054                                        server_id,
10055                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10056                                        server_id,
10057                                    )),
10058                                    proto::language_server_selector::Selector::Name(name) => {
10059                                        LanguageServerSelector::Name(LanguageServerName(
10060                                            SharedString::from(name),
10061                                        ))
10062                                    }
10063                                })
10064                            })
10065                            .collect(),
10066                        cx,
10067                    )
10068                    .detach_and_log_err(cx);
10069            }
10070        })?;
10071
10072        Ok(proto::Ack {})
10073    }
10074
10075    pub async fn handle_cancel_language_server_work(
10076        lsp_store: Entity<Self>,
10077        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10078        mut cx: AsyncApp,
10079    ) -> Result<proto::Ack> {
10080        lsp_store.update(&mut cx, |lsp_store, cx| {
10081            if let Some(work) = envelope.payload.work {
10082                match work {
10083                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10084                        let buffers =
10085                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10086                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10087                    }
10088                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10089                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10090                        let token = work
10091                            .token
10092                            .map(|token| {
10093                                ProgressToken::from_proto(token)
10094                                    .context("invalid work progress token")
10095                            })
10096                            .transpose()?;
10097                        lsp_store.cancel_language_server_work(server_id, token, cx);
10098                    }
10099                }
10100            }
10101            anyhow::Ok(())
10102        })??;
10103
10104        Ok(proto::Ack {})
10105    }
10106
10107    fn buffer_ids_to_buffers(
10108        &mut self,
10109        buffer_ids: impl Iterator<Item = u64>,
10110        cx: &mut Context<Self>,
10111    ) -> Vec<Entity<Buffer>> {
10112        buffer_ids
10113            .into_iter()
10114            .flat_map(|buffer_id| {
10115                self.buffer_store
10116                    .read(cx)
10117                    .get(BufferId::new(buffer_id).log_err()?)
10118            })
10119            .collect::<Vec<_>>()
10120    }
10121
10122    async fn handle_apply_additional_edits_for_completion(
10123        this: Entity<Self>,
10124        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10125        mut cx: AsyncApp,
10126    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10127        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10128            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10129            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10130            let completion = Self::deserialize_completion(
10131                envelope.payload.completion.context("invalid completion")?,
10132            )?;
10133            anyhow::Ok((buffer, completion))
10134        })??;
10135
10136        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10137            this.apply_additional_edits_for_completion(
10138                buffer,
10139                Rc::new(RefCell::new(Box::new([Completion {
10140                    replace_range: completion.replace_range,
10141                    new_text: completion.new_text,
10142                    source: completion.source,
10143                    documentation: None,
10144                    label: CodeLabel::default(),
10145                    match_start: None,
10146                    snippet_deduplication_key: None,
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                    match_start: None,
12852                    snippet_deduplication_key: None,
12853                });
12854            }
12855            None => {
12856                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12857                ensure_uniform_list_compatible_label(&mut label);
12858                completions.push(Completion {
12859                    label,
12860                    documentation: None,
12861                    replace_range: completion.replace_range,
12862                    new_text: completion.new_text,
12863                    source: completion.source,
12864                    insert_text_mode: None,
12865                    icon_path: None,
12866                    confirm: None,
12867                    match_start: None,
12868                    snippet_deduplication_key: None,
12869                });
12870            }
12871        }
12872    }
12873    completions
12874}
12875
12876#[derive(Debug)]
12877pub enum LanguageServerToQuery {
12878    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12879    FirstCapable,
12880    /// Query a specific language server.
12881    Other(LanguageServerId),
12882}
12883
12884#[derive(Default)]
12885struct RenamePathsWatchedForServer {
12886    did_rename: Vec<RenameActionPredicate>,
12887    will_rename: Vec<RenameActionPredicate>,
12888}
12889
12890impl RenamePathsWatchedForServer {
12891    fn with_did_rename_patterns(
12892        mut self,
12893        did_rename: Option<&FileOperationRegistrationOptions>,
12894    ) -> Self {
12895        if let Some(did_rename) = did_rename {
12896            self.did_rename = did_rename
12897                .filters
12898                .iter()
12899                .filter_map(|filter| filter.try_into().log_err())
12900                .collect();
12901        }
12902        self
12903    }
12904    fn with_will_rename_patterns(
12905        mut self,
12906        will_rename: Option<&FileOperationRegistrationOptions>,
12907    ) -> Self {
12908        if let Some(will_rename) = will_rename {
12909            self.will_rename = will_rename
12910                .filters
12911                .iter()
12912                .filter_map(|filter| filter.try_into().log_err())
12913                .collect();
12914        }
12915        self
12916    }
12917
12918    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12919        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12920    }
12921    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12922        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12923    }
12924}
12925
12926impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12927    type Error = globset::Error;
12928    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12929        Ok(Self {
12930            kind: ops.pattern.matches.clone(),
12931            glob: GlobBuilder::new(&ops.pattern.glob)
12932                .case_insensitive(
12933                    ops.pattern
12934                        .options
12935                        .as_ref()
12936                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12937                )
12938                .build()?
12939                .compile_matcher(),
12940        })
12941    }
12942}
12943struct RenameActionPredicate {
12944    glob: GlobMatcher,
12945    kind: Option<FileOperationPatternKind>,
12946}
12947
12948impl RenameActionPredicate {
12949    // Returns true if language server should be notified
12950    fn eval(&self, path: &str, is_dir: bool) -> bool {
12951        self.kind.as_ref().is_none_or(|kind| {
12952            let expected_kind = if is_dir {
12953                FileOperationPatternKind::Folder
12954            } else {
12955                FileOperationPatternKind::File
12956            };
12957            kind == &expected_kind
12958        }) && self.glob.is_match(path)
12959    }
12960}
12961
12962#[derive(Default)]
12963struct LanguageServerWatchedPaths {
12964    worktree_paths: HashMap<WorktreeId, GlobSet>,
12965    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12966}
12967
12968#[derive(Default)]
12969struct LanguageServerWatchedPathsBuilder {
12970    worktree_paths: HashMap<WorktreeId, GlobSet>,
12971    abs_paths: HashMap<Arc<Path>, GlobSet>,
12972}
12973
12974impl LanguageServerWatchedPathsBuilder {
12975    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12976        self.worktree_paths.insert(worktree_id, glob_set);
12977    }
12978    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12979        self.abs_paths.insert(path, glob_set);
12980    }
12981    fn build(
12982        self,
12983        fs: Arc<dyn Fs>,
12984        language_server_id: LanguageServerId,
12985        cx: &mut Context<LspStore>,
12986    ) -> LanguageServerWatchedPaths {
12987        let lsp_store = cx.weak_entity();
12988
12989        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12990        let abs_paths = self
12991            .abs_paths
12992            .into_iter()
12993            .map(|(abs_path, globset)| {
12994                let task = cx.spawn({
12995                    let abs_path = abs_path.clone();
12996                    let fs = fs.clone();
12997
12998                    let lsp_store = lsp_store.clone();
12999                    async move |_, cx| {
13000                        maybe!(async move {
13001                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13002                            while let Some(update) = push_updates.0.next().await {
13003                                let action = lsp_store
13004                                    .update(cx, |this, _| {
13005                                        let Some(local) = this.as_local() else {
13006                                            return ControlFlow::Break(());
13007                                        };
13008                                        let Some(watcher) = local
13009                                            .language_server_watched_paths
13010                                            .get(&language_server_id)
13011                                        else {
13012                                            return ControlFlow::Break(());
13013                                        };
13014                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13015                                            "Watched abs path is not registered with a watcher",
13016                                        );
13017                                        let matching_entries = update
13018                                            .into_iter()
13019                                            .filter(|event| globs.is_match(&event.path))
13020                                            .collect::<Vec<_>>();
13021                                        this.lsp_notify_abs_paths_changed(
13022                                            language_server_id,
13023                                            matching_entries,
13024                                        );
13025                                        ControlFlow::Continue(())
13026                                    })
13027                                    .ok()?;
13028
13029                                if action.is_break() {
13030                                    break;
13031                                }
13032                            }
13033                            Some(())
13034                        })
13035                        .await;
13036                    }
13037                });
13038                (abs_path, (globset, task))
13039            })
13040            .collect();
13041        LanguageServerWatchedPaths {
13042            worktree_paths: self.worktree_paths,
13043            abs_paths,
13044        }
13045    }
13046}
13047
13048struct LspBufferSnapshot {
13049    version: i32,
13050    snapshot: TextBufferSnapshot,
13051}
13052
13053/// A prompt requested by LSP server.
13054#[derive(Clone, Debug)]
13055pub struct LanguageServerPromptRequest {
13056    pub level: PromptLevel,
13057    pub message: String,
13058    pub actions: Vec<MessageActionItem>,
13059    pub lsp_name: String,
13060    pub(crate) response_channel: Sender<MessageActionItem>,
13061}
13062
13063impl LanguageServerPromptRequest {
13064    pub async fn respond(self, index: usize) -> Option<()> {
13065        if let Some(response) = self.actions.into_iter().nth(index) {
13066            self.response_channel.send(response).await.ok()
13067        } else {
13068            None
13069        }
13070    }
13071}
13072impl PartialEq for LanguageServerPromptRequest {
13073    fn eq(&self, other: &Self) -> bool {
13074        self.message == other.message && self.actions == other.actions
13075    }
13076}
13077
13078#[derive(Clone, Debug, PartialEq)]
13079pub enum LanguageServerLogType {
13080    Log(MessageType),
13081    Trace { verbose_info: Option<String> },
13082    Rpc { received: bool },
13083}
13084
13085impl LanguageServerLogType {
13086    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13087        match self {
13088            Self::Log(log_type) => {
13089                use proto::log_message::LogLevel;
13090                let level = match *log_type {
13091                    MessageType::ERROR => LogLevel::Error,
13092                    MessageType::WARNING => LogLevel::Warning,
13093                    MessageType::INFO => LogLevel::Info,
13094                    MessageType::LOG => LogLevel::Log,
13095                    other => {
13096                        log::warn!("Unknown lsp log message type: {other:?}");
13097                        LogLevel::Log
13098                    }
13099                };
13100                proto::language_server_log::LogType::Log(proto::LogMessage {
13101                    level: level as i32,
13102                })
13103            }
13104            Self::Trace { verbose_info } => {
13105                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13106                    verbose_info: verbose_info.to_owned(),
13107                })
13108            }
13109            Self::Rpc { received } => {
13110                let kind = if *received {
13111                    proto::rpc_message::Kind::Received
13112                } else {
13113                    proto::rpc_message::Kind::Sent
13114                };
13115                let kind = kind as i32;
13116                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13117            }
13118        }
13119    }
13120
13121    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13122        use proto::log_message::LogLevel;
13123        use proto::rpc_message;
13124        match log_type {
13125            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13126                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13127                    LogLevel::Error => MessageType::ERROR,
13128                    LogLevel::Warning => MessageType::WARNING,
13129                    LogLevel::Info => MessageType::INFO,
13130                    LogLevel::Log => MessageType::LOG,
13131                },
13132            ),
13133            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13134                verbose_info: trace_message.verbose_info,
13135            },
13136            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13137                received: match rpc_message::Kind::from_i32(message.kind)
13138                    .unwrap_or(rpc_message::Kind::Received)
13139                {
13140                    rpc_message::Kind::Received => true,
13141                    rpc_message::Kind::Sent => false,
13142                },
13143            },
13144        }
13145    }
13146}
13147
13148pub struct WorkspaceRefreshTask {
13149    refresh_tx: mpsc::Sender<()>,
13150    progress_tx: mpsc::Sender<()>,
13151    #[allow(dead_code)]
13152    task: Task<()>,
13153}
13154
13155pub enum LanguageServerState {
13156    Starting {
13157        startup: Task<Option<Arc<LanguageServer>>>,
13158        /// List of language servers that will be added to the workspace once it's initialization completes.
13159        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13160    },
13161
13162    Running {
13163        adapter: Arc<CachedLspAdapter>,
13164        server: Arc<LanguageServer>,
13165        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13166        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13167    },
13168}
13169
13170impl LanguageServerState {
13171    fn add_workspace_folder(&self, uri: Uri) {
13172        match self {
13173            LanguageServerState::Starting {
13174                pending_workspace_folders,
13175                ..
13176            } => {
13177                pending_workspace_folders.lock().insert(uri);
13178            }
13179            LanguageServerState::Running { server, .. } => {
13180                server.add_workspace_folder(uri);
13181            }
13182        }
13183    }
13184    fn _remove_workspace_folder(&self, uri: Uri) {
13185        match self {
13186            LanguageServerState::Starting {
13187                pending_workspace_folders,
13188                ..
13189            } => {
13190                pending_workspace_folders.lock().remove(&uri);
13191            }
13192            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13193        }
13194    }
13195}
13196
13197impl std::fmt::Debug for LanguageServerState {
13198    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13199        match self {
13200            LanguageServerState::Starting { .. } => {
13201                f.debug_struct("LanguageServerState::Starting").finish()
13202            }
13203            LanguageServerState::Running { .. } => {
13204                f.debug_struct("LanguageServerState::Running").finish()
13205            }
13206        }
13207    }
13208}
13209
13210#[derive(Clone, Debug, Serialize)]
13211pub struct LanguageServerProgress {
13212    pub is_disk_based_diagnostics_progress: bool,
13213    pub is_cancellable: bool,
13214    pub title: Option<String>,
13215    pub message: Option<String>,
13216    pub percentage: Option<usize>,
13217    #[serde(skip_serializing)]
13218    pub last_update_at: Instant,
13219}
13220
13221#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13222pub struct DiagnosticSummary {
13223    pub error_count: usize,
13224    pub warning_count: usize,
13225}
13226
13227impl DiagnosticSummary {
13228    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13229        let mut this = Self {
13230            error_count: 0,
13231            warning_count: 0,
13232        };
13233
13234        for entry in diagnostics {
13235            if entry.diagnostic.is_primary {
13236                match entry.diagnostic.severity {
13237                    DiagnosticSeverity::ERROR => this.error_count += 1,
13238                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13239                    _ => {}
13240                }
13241            }
13242        }
13243
13244        this
13245    }
13246
13247    pub fn is_empty(&self) -> bool {
13248        self.error_count == 0 && self.warning_count == 0
13249    }
13250
13251    pub fn to_proto(
13252        self,
13253        language_server_id: LanguageServerId,
13254        path: &RelPath,
13255    ) -> proto::DiagnosticSummary {
13256        proto::DiagnosticSummary {
13257            path: path.to_proto(),
13258            language_server_id: language_server_id.0 as u64,
13259            error_count: self.error_count as u32,
13260            warning_count: self.warning_count as u32,
13261        }
13262    }
13263}
13264
13265#[derive(Clone, Debug)]
13266pub enum CompletionDocumentation {
13267    /// There is no documentation for this completion.
13268    Undocumented,
13269    /// A single line of documentation.
13270    SingleLine(SharedString),
13271    /// Multiple lines of plain text documentation.
13272    MultiLinePlainText(SharedString),
13273    /// Markdown documentation.
13274    MultiLineMarkdown(SharedString),
13275    /// Both single line and multiple lines of plain text documentation.
13276    SingleLineAndMultiLinePlainText {
13277        single_line: SharedString,
13278        plain_text: Option<SharedString>,
13279    },
13280}
13281
13282impl CompletionDocumentation {
13283    #[cfg(any(test, feature = "test-support"))]
13284    pub fn text(&self) -> SharedString {
13285        match self {
13286            CompletionDocumentation::Undocumented => "".into(),
13287            CompletionDocumentation::SingleLine(s) => s.clone(),
13288            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13289            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13290            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13291                single_line.clone()
13292            }
13293        }
13294    }
13295}
13296
13297impl From<lsp::Documentation> for CompletionDocumentation {
13298    fn from(docs: lsp::Documentation) -> Self {
13299        match docs {
13300            lsp::Documentation::String(text) => {
13301                if text.lines().count() <= 1 {
13302                    CompletionDocumentation::SingleLine(text.into())
13303                } else {
13304                    CompletionDocumentation::MultiLinePlainText(text.into())
13305                }
13306            }
13307
13308            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13309                lsp::MarkupKind::PlainText => {
13310                    if value.lines().count() <= 1 {
13311                        CompletionDocumentation::SingleLine(value.into())
13312                    } else {
13313                        CompletionDocumentation::MultiLinePlainText(value.into())
13314                    }
13315                }
13316
13317                lsp::MarkupKind::Markdown => {
13318                    CompletionDocumentation::MultiLineMarkdown(value.into())
13319                }
13320            },
13321        }
13322    }
13323}
13324
13325pub enum ResolvedHint {
13326    Resolved(InlayHint),
13327    Resolving(Shared<Task<()>>),
13328}
13329
13330fn glob_literal_prefix(glob: &Path) -> PathBuf {
13331    glob.components()
13332        .take_while(|component| match component {
13333            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13334            _ => true,
13335        })
13336        .collect()
13337}
13338
13339pub struct SshLspAdapter {
13340    name: LanguageServerName,
13341    binary: LanguageServerBinary,
13342    initialization_options: Option<String>,
13343    code_action_kinds: Option<Vec<CodeActionKind>>,
13344}
13345
13346impl SshLspAdapter {
13347    pub fn new(
13348        name: LanguageServerName,
13349        binary: LanguageServerBinary,
13350        initialization_options: Option<String>,
13351        code_action_kinds: Option<String>,
13352    ) -> Self {
13353        Self {
13354            name,
13355            binary,
13356            initialization_options,
13357            code_action_kinds: code_action_kinds
13358                .as_ref()
13359                .and_then(|c| serde_json::from_str(c).ok()),
13360        }
13361    }
13362}
13363
13364impl LspInstaller for SshLspAdapter {
13365    type BinaryVersion = ();
13366    async fn check_if_user_installed(
13367        &self,
13368        _: &dyn LspAdapterDelegate,
13369        _: Option<Toolchain>,
13370        _: &AsyncApp,
13371    ) -> Option<LanguageServerBinary> {
13372        Some(self.binary.clone())
13373    }
13374
13375    async fn cached_server_binary(
13376        &self,
13377        _: PathBuf,
13378        _: &dyn LspAdapterDelegate,
13379    ) -> Option<LanguageServerBinary> {
13380        None
13381    }
13382
13383    async fn fetch_latest_server_version(
13384        &self,
13385        _: &dyn LspAdapterDelegate,
13386        _: bool,
13387        _: &mut AsyncApp,
13388    ) -> Result<()> {
13389        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13390    }
13391
13392    async fn fetch_server_binary(
13393        &self,
13394        _: (),
13395        _: PathBuf,
13396        _: &dyn LspAdapterDelegate,
13397    ) -> Result<LanguageServerBinary> {
13398        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13399    }
13400}
13401
13402#[async_trait(?Send)]
13403impl LspAdapter for SshLspAdapter {
13404    fn name(&self) -> LanguageServerName {
13405        self.name.clone()
13406    }
13407
13408    async fn initialization_options(
13409        self: Arc<Self>,
13410        _: &Arc<dyn LspAdapterDelegate>,
13411    ) -> Result<Option<serde_json::Value>> {
13412        let Some(options) = &self.initialization_options else {
13413            return Ok(None);
13414        };
13415        let result = serde_json::from_str(options)?;
13416        Ok(result)
13417    }
13418
13419    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13420        self.code_action_kinds.clone()
13421    }
13422}
13423
13424pub fn language_server_settings<'a>(
13425    delegate: &'a dyn LspAdapterDelegate,
13426    language: &LanguageServerName,
13427    cx: &'a App,
13428) -> Option<&'a LspSettings> {
13429    language_server_settings_for(
13430        SettingsLocation {
13431            worktree_id: delegate.worktree_id(),
13432            path: RelPath::empty(),
13433        },
13434        language,
13435        cx,
13436    )
13437}
13438
13439pub(crate) fn language_server_settings_for<'a>(
13440    location: SettingsLocation<'a>,
13441    language: &LanguageServerName,
13442    cx: &'a App,
13443) -> Option<&'a LspSettings> {
13444    ProjectSettings::get(Some(location), cx).lsp.get(language)
13445}
13446
13447pub struct LocalLspAdapterDelegate {
13448    lsp_store: WeakEntity<LspStore>,
13449    worktree: worktree::Snapshot,
13450    fs: Arc<dyn Fs>,
13451    http_client: Arc<dyn HttpClient>,
13452    language_registry: Arc<LanguageRegistry>,
13453    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13454}
13455
13456impl LocalLspAdapterDelegate {
13457    pub fn new(
13458        language_registry: Arc<LanguageRegistry>,
13459        environment: &Entity<ProjectEnvironment>,
13460        lsp_store: WeakEntity<LspStore>,
13461        worktree: &Entity<Worktree>,
13462        http_client: Arc<dyn HttpClient>,
13463        fs: Arc<dyn Fs>,
13464        cx: &mut App,
13465    ) -> Arc<Self> {
13466        let load_shell_env_task =
13467            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13468
13469        Arc::new(Self {
13470            lsp_store,
13471            worktree: worktree.read(cx).snapshot(),
13472            fs,
13473            http_client,
13474            language_registry,
13475            load_shell_env_task,
13476        })
13477    }
13478
13479    fn from_local_lsp(
13480        local: &LocalLspStore,
13481        worktree: &Entity<Worktree>,
13482        cx: &mut App,
13483    ) -> Arc<Self> {
13484        Self::new(
13485            local.languages.clone(),
13486            &local.environment,
13487            local.weak.clone(),
13488            worktree,
13489            local.http_client.clone(),
13490            local.fs.clone(),
13491            cx,
13492        )
13493    }
13494}
13495
13496#[async_trait]
13497impl LspAdapterDelegate for LocalLspAdapterDelegate {
13498    fn show_notification(&self, message: &str, cx: &mut App) {
13499        self.lsp_store
13500            .update(cx, |_, cx| {
13501                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13502            })
13503            .ok();
13504    }
13505
13506    fn http_client(&self) -> Arc<dyn HttpClient> {
13507        self.http_client.clone()
13508    }
13509
13510    fn worktree_id(&self) -> WorktreeId {
13511        self.worktree.id()
13512    }
13513
13514    fn worktree_root_path(&self) -> &Path {
13515        self.worktree.abs_path().as_ref()
13516    }
13517
13518    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13519        self.worktree.resolve_executable_path(path)
13520    }
13521
13522    async fn shell_env(&self) -> HashMap<String, String> {
13523        let task = self.load_shell_env_task.clone();
13524        task.await.unwrap_or_default()
13525    }
13526
13527    async fn npm_package_installed_version(
13528        &self,
13529        package_name: &str,
13530    ) -> Result<Option<(PathBuf, String)>> {
13531        let local_package_directory = self.worktree_root_path();
13532        let node_modules_directory = local_package_directory.join("node_modules");
13533
13534        if let Some(version) =
13535            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13536        {
13537            return Ok(Some((node_modules_directory, version)));
13538        }
13539        let Some(npm) = self.which("npm".as_ref()).await else {
13540            log::warn!(
13541                "Failed to find npm executable for {:?}",
13542                local_package_directory
13543            );
13544            return Ok(None);
13545        };
13546
13547        let env = self.shell_env().await;
13548        let output = util::command::new_smol_command(&npm)
13549            .args(["root", "-g"])
13550            .envs(env)
13551            .current_dir(local_package_directory)
13552            .output()
13553            .await?;
13554        let global_node_modules =
13555            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13556
13557        if let Some(version) =
13558            read_package_installed_version(global_node_modules.clone(), package_name).await?
13559        {
13560            return Ok(Some((global_node_modules, version)));
13561        }
13562        return Ok(None);
13563    }
13564
13565    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13566        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13567        if self.fs.is_file(&worktree_abs_path).await {
13568            worktree_abs_path.pop();
13569        }
13570
13571        let env = self.shell_env().await;
13572
13573        let shell_path = env.get("PATH").cloned();
13574
13575        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13576    }
13577
13578    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13579        let mut working_dir = self.worktree_root_path().to_path_buf();
13580        if self.fs.is_file(&working_dir).await {
13581            working_dir.pop();
13582        }
13583        let output = util::command::new_smol_command(&command.path)
13584            .args(command.arguments)
13585            .envs(command.env.clone().unwrap_or_default())
13586            .current_dir(working_dir)
13587            .output()
13588            .await?;
13589
13590        anyhow::ensure!(
13591            output.status.success(),
13592            "{}, stdout: {:?}, stderr: {:?}",
13593            output.status,
13594            String::from_utf8_lossy(&output.stdout),
13595            String::from_utf8_lossy(&output.stderr)
13596        );
13597        Ok(())
13598    }
13599
13600    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13601        self.language_registry
13602            .update_lsp_binary_status(server_name, status);
13603    }
13604
13605    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13606        self.language_registry
13607            .all_lsp_adapters()
13608            .into_iter()
13609            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13610            .collect()
13611    }
13612
13613    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13614        let dir = self.language_registry.language_server_download_dir(name)?;
13615
13616        if !dir.exists() {
13617            smol::fs::create_dir_all(&dir)
13618                .await
13619                .context("failed to create container directory")
13620                .log_err()?;
13621        }
13622
13623        Some(dir)
13624    }
13625
13626    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13627        let entry = self
13628            .worktree
13629            .entry_for_path(path)
13630            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13631        let abs_path = self.worktree.absolutize(&entry.path);
13632        self.fs.load(&abs_path).await
13633    }
13634}
13635
13636async fn populate_labels_for_symbols(
13637    symbols: Vec<CoreSymbol>,
13638    language_registry: &Arc<LanguageRegistry>,
13639    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13640    output: &mut Vec<Symbol>,
13641) {
13642    #[allow(clippy::mutable_key_type)]
13643    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13644
13645    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13646    for symbol in symbols {
13647        let Some(file_name) = symbol.path.file_name() else {
13648            continue;
13649        };
13650        let language = language_registry
13651            .load_language_for_file_path(Path::new(file_name))
13652            .await
13653            .ok()
13654            .or_else(|| {
13655                unknown_paths.insert(file_name.into());
13656                None
13657            });
13658        symbols_by_language
13659            .entry(language)
13660            .or_default()
13661            .push(symbol);
13662    }
13663
13664    for unknown_path in unknown_paths {
13665        log::info!("no language found for symbol in file {unknown_path:?}");
13666    }
13667
13668    let mut label_params = Vec::new();
13669    for (language, mut symbols) in symbols_by_language {
13670        label_params.clear();
13671        label_params.extend(
13672            symbols
13673                .iter_mut()
13674                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13675        );
13676
13677        let mut labels = Vec::new();
13678        if let Some(language) = language {
13679            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13680                language_registry
13681                    .lsp_adapters(&language.name())
13682                    .first()
13683                    .cloned()
13684            });
13685            if let Some(lsp_adapter) = lsp_adapter {
13686                labels = lsp_adapter
13687                    .labels_for_symbols(&label_params, &language)
13688                    .await
13689                    .log_err()
13690                    .unwrap_or_default();
13691            }
13692        }
13693
13694        for ((symbol, (name, _)), label) in symbols
13695            .into_iter()
13696            .zip(label_params.drain(..))
13697            .zip(labels.into_iter().chain(iter::repeat(None)))
13698        {
13699            output.push(Symbol {
13700                language_server_name: symbol.language_server_name,
13701                source_worktree_id: symbol.source_worktree_id,
13702                source_language_server_id: symbol.source_language_server_id,
13703                path: symbol.path,
13704                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13705                name,
13706                kind: symbol.kind,
13707                range: symbol.range,
13708            });
13709        }
13710    }
13711}
13712
13713fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13714    match server.capabilities().text_document_sync.as_ref()? {
13715        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13716            // Server wants didSave but didn't specify includeText.
13717            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13718            // Server doesn't want didSave at all.
13719            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13720            // Server provided SaveOptions.
13721            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13722                Some(save_options.include_text.unwrap_or(false))
13723            }
13724        },
13725        // We do not have any save info. Kind affects didChange only.
13726        lsp::TextDocumentSyncCapability::Kind(_) => None,
13727    }
13728}
13729
13730/// Completion items are displayed in a `UniformList`.
13731/// Usually, those items are single-line strings, but in LSP responses,
13732/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13733/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13734/// 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,
13735/// breaking the completions menu presentation.
13736///
13737/// 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.
13738fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13739    let mut new_text = String::with_capacity(label.text.len());
13740    let mut offset_map = vec![0; label.text.len() + 1];
13741    let mut last_char_was_space = false;
13742    let mut new_idx = 0;
13743    let chars = label.text.char_indices().fuse();
13744    let mut newlines_removed = false;
13745
13746    for (idx, c) in chars {
13747        offset_map[idx] = new_idx;
13748
13749        match c {
13750            '\n' if last_char_was_space => {
13751                newlines_removed = true;
13752            }
13753            '\t' | ' ' if last_char_was_space => {}
13754            '\n' if !last_char_was_space => {
13755                new_text.push(' ');
13756                new_idx += 1;
13757                last_char_was_space = true;
13758                newlines_removed = true;
13759            }
13760            ' ' | '\t' => {
13761                new_text.push(' ');
13762                new_idx += 1;
13763                last_char_was_space = true;
13764            }
13765            _ => {
13766                new_text.push(c);
13767                new_idx += c.len_utf8();
13768                last_char_was_space = false;
13769            }
13770        }
13771    }
13772    offset_map[label.text.len()] = new_idx;
13773
13774    // Only modify the label if newlines were removed.
13775    if !newlines_removed {
13776        return;
13777    }
13778
13779    let last_index = new_idx;
13780    let mut run_ranges_errors = Vec::new();
13781    label.runs.retain_mut(|(range, _)| {
13782        match offset_map.get(range.start) {
13783            Some(&start) => range.start = start,
13784            None => {
13785                run_ranges_errors.push(range.clone());
13786                return false;
13787            }
13788        }
13789
13790        match offset_map.get(range.end) {
13791            Some(&end) => range.end = end,
13792            None => {
13793                run_ranges_errors.push(range.clone());
13794                range.end = last_index;
13795            }
13796        }
13797        true
13798    });
13799    if !run_ranges_errors.is_empty() {
13800        log::error!(
13801            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13802            label.text
13803        );
13804    }
13805
13806    let mut wrong_filter_range = None;
13807    if label.filter_range == (0..label.text.len()) {
13808        label.filter_range = 0..new_text.len();
13809    } else {
13810        let mut original_filter_range = Some(label.filter_range.clone());
13811        match offset_map.get(label.filter_range.start) {
13812            Some(&start) => label.filter_range.start = start,
13813            None => {
13814                wrong_filter_range = original_filter_range.take();
13815                label.filter_range.start = last_index;
13816            }
13817        }
13818
13819        match offset_map.get(label.filter_range.end) {
13820            Some(&end) => label.filter_range.end = end,
13821            None => {
13822                wrong_filter_range = original_filter_range.take();
13823                label.filter_range.end = last_index;
13824            }
13825        }
13826    }
13827    if let Some(wrong_filter_range) = wrong_filter_range {
13828        log::error!(
13829            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13830            label.text
13831        );
13832    }
13833
13834    label.text = new_text;
13835}
13836
13837#[cfg(test)]
13838mod tests {
13839    use language::HighlightId;
13840
13841    use super::*;
13842
13843    #[test]
13844    fn test_glob_literal_prefix() {
13845        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13846        assert_eq!(
13847            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13848            Path::new("node_modules")
13849        );
13850        assert_eq!(
13851            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13852            Path::new("foo")
13853        );
13854        assert_eq!(
13855            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13856            Path::new("foo/bar/baz.js")
13857        );
13858
13859        #[cfg(target_os = "windows")]
13860        {
13861            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13862            assert_eq!(
13863                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13864                Path::new("node_modules")
13865            );
13866            assert_eq!(
13867                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13868                Path::new("foo")
13869            );
13870            assert_eq!(
13871                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13872                Path::new("foo/bar/baz.js")
13873            );
13874        }
13875    }
13876
13877    #[test]
13878    fn test_multi_len_chars_normalization() {
13879        let mut label = CodeLabel::new(
13880            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13881            0..6,
13882            vec![(0..6, HighlightId(1))],
13883        );
13884        ensure_uniform_list_compatible_label(&mut label);
13885        assert_eq!(
13886            label,
13887            CodeLabel::new(
13888                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13889                0..6,
13890                vec![(0..6, HighlightId(1))],
13891            )
13892        );
13893    }
13894}