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;
   13mod code_lens;
   14mod document_colors;
   15mod document_symbols;
   16mod folding_ranges;
   17mod inlay_hints;
   18pub mod json_language_server_ext;
   19pub mod log_store;
   20pub mod lsp_ext_command;
   21pub mod rust_analyzer_ext;
   22mod semantic_tokens;
   23pub mod vue_language_server_ext;
   24
   25use self::code_lens::CodeLensData;
   26use self::document_colors::DocumentColorData;
   27use self::document_symbols::DocumentSymbolsData;
   28use self::inlay_hints::BufferInlayHints;
   29use crate::{
   30    CodeAction, Completion, CompletionDisplayOptions, CompletionResponse, CompletionSource,
   31    CoreCompletion, Hover, InlayHint, InlayId, LocationLink, LspAction, LspPullDiagnostics,
   32    ManifestProvidersStore, Project, ProjectItem, ProjectPath, ProjectTransaction,
   33    PulledDiagnostics, ResolveState, Symbol,
   34    buffer_store::{BufferStore, BufferStoreEvent},
   35    environment::ProjectEnvironment,
   36    lsp_command::{self, *},
   37    lsp_store::{
   38        self,
   39        folding_ranges::FoldingRangeData,
   40        log_store::{GlobalLogStore, LanguageServerKind},
   41        semantic_tokens::{SemanticTokenConfig, SemanticTokensData},
   42    },
   43    manifest_tree::{
   44        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   45        ManifestTree,
   46    },
   47    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   48    project_settings::{BinarySettings, LspSettings, ProjectSettings},
   49    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   50    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   51    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   52    yarn::YarnPathStore,
   53};
   54use anyhow::{Context as _, Result, anyhow};
   55use async_trait::async_trait;
   56use client::{TypedEnvelope, proto};
   57use clock::Global;
   58use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   59use futures::{
   60    AsyncWriteExt, Future, FutureExt, StreamExt,
   61    future::{Either, Shared, join_all, pending, select},
   62    select, select_biased,
   63    stream::FuturesUnordered,
   64};
   65use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   66use gpui::{
   67    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   68    Subscription, Task, WeakEntity,
   69};
   70use http_client::HttpClient;
   71use itertools::Itertools as _;
   72use language::{
   73    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   74    CodeLabelExt, Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff,
   75    File as _, Language, LanguageAwareStyling, LanguageName, LanguageRegistry, LocalFile,
   76    LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate, ManifestName, ModelineSettings,
   77    OffsetUtf16, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToOffsetUtf16, ToPointUtf16,
   78    Toolchain, Transaction, Unclipped,
   79    language_settings::{
   80        AllLanguageSettings, FormatOnSave, Formatter, LanguageSettings, LineEndingSetting,
   81        all_language_settings,
   82    },
   83    modeline, point_to_lsp,
   84    proto::{
   85        deserialize_anchor, deserialize_anchor_range, deserialize_version, serialize_anchor,
   86        serialize_anchor_range, serialize_version,
   87    },
   88    range_from_lsp, range_to_lsp,
   89    row_chunk::RowChunk,
   90};
   91use lsp::{
   92    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   93    DEFAULT_LSP_REQUEST_TIMEOUT, DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   94    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   95    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LanguageServer,
   96    LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId, LanguageServerName,
   97    LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType, OneOf,
   98    RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles,
   99    WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
  100};
  101use node_runtime::read_package_installed_version;
  102use parking_lot::Mutex;
  103use postage::{mpsc, sink::Sink, stream::Stream, watch};
  104use rand::prelude::*;
  105use rpc::{
  106    AnyProtoClient, ErrorCode, ErrorExt as _,
  107    proto::{LspRequestId, LspRequestMessage as _},
  108};
  109use semver::Version;
  110use serde::Serialize;
  111use serde_json::Value;
  112use settings::{Settings, SettingsLocation, SettingsStore};
  113use sha2::{Digest, Sha256};
  114use snippet::Snippet;
  115use std::{
  116    any::TypeId,
  117    borrow::Cow,
  118    cell::RefCell,
  119    cmp::{Ordering, Reverse},
  120    collections::{VecDeque, hash_map},
  121    convert::TryInto,
  122    ffi::OsStr,
  123    future::ready,
  124    iter, mem,
  125    ops::{ControlFlow, Range},
  126    path::{self, Path, PathBuf},
  127    pin::pin,
  128    rc::Rc,
  129    sync::{
  130        Arc,
  131        atomic::{self, AtomicUsize},
  132    },
  133    time::{Duration, Instant},
  134    vec,
  135};
  136use sum_tree::Dimensions;
  137use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  138
  139use util::{
  140    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  141    paths::{PathStyle, SanitizedPath, UrlExt},
  142    post_inc,
  143    redact::redact_command,
  144    rel_path::RelPath,
  145};
  146
  147pub use document_colors::DocumentColors;
  148pub use folding_ranges::LspFoldingRange;
  149pub use fs::*;
  150pub use language::Location;
  151pub use lsp_store::inlay_hints::{CacheInlayHints, InvalidationStrategy};
  152#[cfg(any(test, feature = "test-support"))]
  153pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  154#[cfg(any(test, feature = "test-support"))]
  155pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;
  156pub use semantic_tokens::{
  157    BufferSemanticToken, BufferSemanticTokens, RefreshForServer, SemanticTokenStylizer, TokenType,
  158};
  159
  160pub use worktree::{
  161    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  162    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  163};
  164
  165const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  166pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  167const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  168const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  169static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  170
  171#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  172pub enum ProgressToken {
  173    Number(i32),
  174    String(SharedString),
  175}
  176
  177impl std::fmt::Display for ProgressToken {
  178    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  179        match self {
  180            Self::Number(number) => write!(f, "{number}"),
  181            Self::String(string) => write!(f, "{string}"),
  182        }
  183    }
  184}
  185
  186impl ProgressToken {
  187    fn from_lsp(value: lsp::NumberOrString) -> Self {
  188        match value {
  189            lsp::NumberOrString::Number(number) => Self::Number(number),
  190            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  191        }
  192    }
  193
  194    fn to_lsp(&self) -> lsp::NumberOrString {
  195        match self {
  196            Self::Number(number) => lsp::NumberOrString::Number(*number),
  197            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  198        }
  199    }
  200
  201    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  202        Some(match value.value? {
  203            proto::progress_token::Value::Number(number) => Self::Number(number),
  204            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  205        })
  206    }
  207
  208    fn to_proto(&self) -> proto::ProgressToken {
  209        proto::ProgressToken {
  210            value: Some(match self {
  211                Self::Number(number) => proto::progress_token::Value::Number(*number),
  212                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  213            }),
  214        }
  215    }
  216}
  217
  218#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  219pub enum FormatTrigger {
  220    Save,
  221    Manual,
  222}
  223
  224pub enum LspFormatTarget {
  225    Buffers,
  226    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  227}
  228
  229#[derive(Debug, Clone, PartialEq, Eq, Hash)]
  230pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  231
  232struct OpenLspBuffer(Entity<Buffer>);
  233
  234impl FormatTrigger {
  235    fn from_proto(value: i32) -> FormatTrigger {
  236        match value {
  237            0 => FormatTrigger::Save,
  238            1 => FormatTrigger::Manual,
  239            _ => FormatTrigger::Save,
  240        }
  241    }
  242}
  243
  244#[derive(Clone)]
  245struct UnifiedLanguageServer {
  246    id: LanguageServerId,
  247    project_roots: HashSet<Arc<RelPath>>,
  248}
  249
  250/// Settings that affect language server identity.
  251///
  252/// Dynamic settings (`LspSettings::settings`) are excluded because they can be
  253/// updated via `workspace/didChangeConfiguration` without restarting the server.
  254#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  255struct LanguageServerSeedSettings {
  256    binary: Option<BinarySettings>,
  257    initialization_options: Option<serde_json::Value>,
  258}
  259
  260#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  261struct LanguageServerSeed {
  262    worktree_id: WorktreeId,
  263    name: LanguageServerName,
  264    toolchain: Option<Toolchain>,
  265    settings: LanguageServerSeedSettings,
  266}
  267
  268#[derive(Debug)]
  269pub struct DocumentDiagnosticsUpdate<'a, D> {
  270    pub diagnostics: D,
  271    pub result_id: Option<SharedString>,
  272    pub registration_id: Option<SharedString>,
  273    pub server_id: LanguageServerId,
  274    pub disk_based_sources: Cow<'a, [String]>,
  275}
  276
  277pub struct DocumentDiagnostics {
  278    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  279    document_abs_path: PathBuf,
  280    version: Option<i32>,
  281}
  282
  283#[derive(Default, Debug)]
  284struct DynamicRegistrations {
  285    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  286    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  287}
  288
  289pub struct LocalLspStore {
  290    weak: WeakEntity<LspStore>,
  291    pub worktree_store: Entity<WorktreeStore>,
  292    toolchain_store: Entity<LocalToolchainStore>,
  293    http_client: Arc<dyn HttpClient>,
  294    environment: Entity<ProjectEnvironment>,
  295    fs: Arc<dyn Fs>,
  296    languages: Arc<LanguageRegistry>,
  297    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  298    yarn: Entity<YarnPathStore>,
  299    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  300    buffers_being_formatted: HashSet<BufferId>,
  301    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  302    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  303    watched_manifest_filenames: HashSet<ManifestName>,
  304    language_server_paths_watched_for_rename:
  305        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  306    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  307    supplementary_language_servers:
  308        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  309    prettier_store: Entity<PrettierStore>,
  310    next_diagnostic_group_id: usize,
  311    diagnostics: HashMap<
  312        WorktreeId,
  313        HashMap<
  314            Arc<RelPath>,
  315            Vec<(
  316                LanguageServerId,
  317                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  318            )>,
  319        >,
  320    >,
  321    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  322    _subscription: gpui::Subscription,
  323    lsp_tree: LanguageServerTree,
  324    registered_buffers: HashMap<BufferId, usize>,
  325    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  326    buffer_pull_diagnostics_result_ids: HashMap<
  327        LanguageServerId,
  328        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  329    >,
  330    workspace_pull_diagnostics_result_ids: HashMap<
  331        LanguageServerId,
  332        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  333    >,
  334    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  335
  336    buffers_to_refresh_hash_set: HashSet<BufferId>,
  337    buffers_to_refresh_queue: VecDeque<BufferId>,
  338    _background_diagnostics_worker: Shared<Task<()>>,
  339}
  340
  341impl LocalLspStore {
  342    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  343    pub fn running_language_server_for_id(
  344        &self,
  345        id: LanguageServerId,
  346    ) -> Option<&Arc<LanguageServer>> {
  347        let language_server_state = self.language_servers.get(&id)?;
  348
  349        match language_server_state {
  350            LanguageServerState::Running { server, .. } => Some(server),
  351            LanguageServerState::Starting { .. } => None,
  352        }
  353    }
  354
  355    fn get_or_insert_language_server(
  356        &mut self,
  357        worktree_handle: &Entity<Worktree>,
  358        delegate: Arc<LocalLspAdapterDelegate>,
  359        disposition: &Arc<LaunchDisposition>,
  360        language_name: &LanguageName,
  361        cx: &mut App,
  362    ) -> LanguageServerId {
  363        let key = LanguageServerSeed {
  364            worktree_id: worktree_handle.read(cx).id(),
  365            name: disposition.server_name.clone(),
  366            settings: LanguageServerSeedSettings {
  367                binary: disposition.settings.binary.clone(),
  368                initialization_options: disposition.settings.initialization_options.clone(),
  369            },
  370            toolchain: disposition.toolchain.clone(),
  371        };
  372        if let Some(state) = self.language_server_ids.get_mut(&key) {
  373            state.project_roots.insert(disposition.path.path.clone());
  374            state.id
  375        } else {
  376            let adapter = self
  377                .languages
  378                .lsp_adapters(language_name)
  379                .into_iter()
  380                .find(|adapter| adapter.name() == disposition.server_name)
  381                .expect("To find LSP adapter");
  382            let new_language_server_id = self.start_language_server(
  383                worktree_handle,
  384                delegate,
  385                adapter,
  386                disposition.settings.clone(),
  387                key.clone(),
  388                language_name.clone(),
  389                cx,
  390            );
  391            if let Some(state) = self.language_server_ids.get_mut(&key) {
  392                state.project_roots.insert(disposition.path.path.clone());
  393            } else {
  394                debug_assert!(
  395                    false,
  396                    "Expected `start_language_server` to ensure that `key` exists in a map"
  397                );
  398            }
  399            new_language_server_id
  400        }
  401    }
  402
  403    fn start_language_server(
  404        &mut self,
  405        worktree_handle: &Entity<Worktree>,
  406        delegate: Arc<LocalLspAdapterDelegate>,
  407        adapter: Arc<CachedLspAdapter>,
  408        settings: Arc<LspSettings>,
  409        key: LanguageServerSeed,
  410        language_name: LanguageName,
  411        cx: &mut App,
  412    ) -> LanguageServerId {
  413        let worktree = worktree_handle.read(cx);
  414
  415        let worktree_id = worktree.id();
  416        let worktree_abs_path = worktree.abs_path();
  417        let toolchain = key.toolchain.clone();
  418        let override_options = settings.initialization_options.clone();
  419
  420        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  421
  422        let server_id = self.languages.next_language_server_id();
  423        log::trace!(
  424            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  425            adapter.name.0
  426        );
  427
  428        let wait_until_worktree_trust =
  429            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  430                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  431                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  432                });
  433                if can_trust {
  434                    self.restricted_worktrees_tasks.remove(&worktree_id);
  435                    None
  436                } else {
  437                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  438                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  439                        hash_map::Entry::Vacant(v) => {
  440                            let (mut tx, rx) = watch::channel::<bool>();
  441                            let lsp_store = self.weak.clone();
  442                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  443                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  444                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  445                                        tx.blocking_send(true).ok();
  446                                        lsp_store
  447                                            .update(cx, |lsp_store, _| {
  448                                                if let Some(local_lsp_store) =
  449                                                    lsp_store.as_local_mut()
  450                                                {
  451                                                    local_lsp_store
  452                                                        .restricted_worktrees_tasks
  453                                                        .remove(&worktree_id);
  454                                                }
  455                                            })
  456                                            .ok();
  457                                    }
  458                                }
  459                            });
  460                            v.insert((subscription, rx.clone()));
  461                            Some(rx)
  462                        }
  463                    }
  464                }
  465            });
  466        let update_binary_status = wait_until_worktree_trust.is_none();
  467
  468        let binary = self.get_language_server_binary(
  469            worktree_abs_path.clone(),
  470            adapter.clone(),
  471            settings,
  472            toolchain.clone(),
  473            delegate.clone(),
  474            true,
  475            wait_until_worktree_trust,
  476            cx,
  477        );
  478        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  479
  480        let pending_server = cx.spawn({
  481            let adapter = adapter.clone();
  482            let server_name = adapter.name.clone();
  483            let stderr_capture = stderr_capture.clone();
  484            #[cfg(any(test, feature = "test-support"))]
  485            let lsp_store = self.weak.clone();
  486            let pending_workspace_folders = pending_workspace_folders.clone();
  487            async move |cx| {
  488                let binary = binary.await?;
  489                #[cfg(any(test, feature = "test-support"))]
  490                if let Some(server) = lsp_store
  491                    .update(&mut cx.clone(), |this, cx| {
  492                        this.languages.create_fake_language_server(
  493                            server_id,
  494                            &server_name,
  495                            binary.clone(),
  496                            &mut cx.to_async(),
  497                        )
  498                    })
  499                    .ok()
  500                    .flatten()
  501                {
  502                    return Ok(server);
  503                }
  504
  505                let code_action_kinds = adapter.code_action_kinds();
  506                lsp::LanguageServer::new(
  507                    stderr_capture,
  508                    server_id,
  509                    server_name,
  510                    binary,
  511                    &worktree_abs_path,
  512                    code_action_kinds,
  513                    Some(pending_workspace_folders),
  514                    cx,
  515                )
  516            }
  517        });
  518
  519        let startup = {
  520            let server_name = adapter.name.0.clone();
  521            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  522            let key = key.clone();
  523            let adapter = adapter.clone();
  524            let lsp_store = self.weak.clone();
  525            let pending_workspace_folders = pending_workspace_folders.clone();
  526            let pull_diagnostics = ProjectSettings::get_global(cx)
  527                .diagnostics
  528                .lsp_pull_diagnostics
  529                .enabled;
  530            let settings_location = SettingsLocation {
  531                worktree_id,
  532                path: RelPath::empty(),
  533            };
  534            let augments_syntax_tokens = AllLanguageSettings::get(Some(settings_location), cx)
  535                .language(Some(settings_location), Some(&language_name), cx)
  536                .semantic_tokens
  537                .use_tree_sitter();
  538            cx.spawn(async move |cx| {
  539                let result = async {
  540                    let language_server = pending_server.await?;
  541
  542                    let workspace_config = Self::workspace_configuration_for_adapter(
  543                        adapter.adapter.clone(),
  544                        &delegate,
  545                        toolchain,
  546                        None,
  547                        cx,
  548                    )
  549                    .await?;
  550
  551                    let mut initialization_options = Self::initialization_options_for_adapter(
  552                        adapter.adapter.clone(),
  553                        &delegate,
  554                        cx,
  555                    )
  556                    .await?;
  557
  558                    match (&mut initialization_options, override_options) {
  559                        (Some(initialization_options), Some(override_options)) => {
  560                            merge_json_value_into(override_options, initialization_options);
  561                        }
  562                        (None, override_options) => initialization_options = override_options,
  563                        _ => {}
  564                    }
  565
  566                    let initialization_params = cx.update(|cx| {
  567                        let mut params = language_server.default_initialize_params(
  568                            pull_diagnostics,
  569                            augments_syntax_tokens,
  570                            cx,
  571                        );
  572                        params.initialization_options = initialization_options;
  573                        adapter.adapter.prepare_initialize_params(params, cx)
  574                    })?;
  575
  576                    Self::setup_lsp_messages(
  577                        lsp_store.clone(),
  578                        &language_server,
  579                        delegate.clone(),
  580                        adapter.clone(),
  581                    );
  582
  583                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  584                        settings: workspace_config,
  585                    };
  586                    let language_server = cx
  587                        .update(|cx| {
  588                            let request_timeout = ProjectSettings::get_global(cx)
  589                                .global_lsp_settings
  590                                .get_request_timeout();
  591
  592                            language_server.initialize(
  593                                initialization_params,
  594                                Arc::new(did_change_configuration_params.clone()),
  595                                request_timeout,
  596                                cx,
  597                            )
  598                        })
  599                        .await
  600                        .inspect_err(|_| {
  601                            if let Some(lsp_store) = lsp_store.upgrade() {
  602                                lsp_store.update(cx, |lsp_store, cx| {
  603                                    lsp_store.cleanup_lsp_data(server_id);
  604                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  605                                });
  606                            }
  607                        })?;
  608
  609                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  610                        did_change_configuration_params,
  611                    )?;
  612
  613                    anyhow::Ok(language_server)
  614                }
  615                .await;
  616
  617                match result {
  618                    Ok(server) => {
  619                        lsp_store
  620                            .update(cx, |lsp_store, cx| {
  621                                lsp_store.insert_newly_running_language_server(
  622                                    adapter,
  623                                    server.clone(),
  624                                    server_id,
  625                                    key,
  626                                    pending_workspace_folders,
  627                                    cx,
  628                                );
  629                            })
  630                            .ok();
  631                        stderr_capture.lock().take();
  632                        Some(server)
  633                    }
  634
  635                    Err(err) => {
  636                        let log = stderr_capture.lock().take().unwrap_or_default();
  637                        delegate.update_status(
  638                            adapter.name(),
  639                            BinaryStatus::Failed {
  640                                error: if log.is_empty() {
  641                                    format!("{err:#}")
  642                                } else {
  643                                    format!("{err:#}\n-- stderr --\n{log}")
  644                                },
  645                            },
  646                        );
  647                        log::error!(
  648                            "Failed to start language server {server_name:?}: {}",
  649                            redact_command(&format!("{err:?}"))
  650                        );
  651                        if !log.is_empty() {
  652                            log::error!("server stderr: {}", redact_command(&log));
  653                        }
  654                        None
  655                    }
  656                }
  657            })
  658        };
  659        let state = LanguageServerState::Starting {
  660            startup,
  661            pending_workspace_folders,
  662        };
  663
  664        if update_binary_status {
  665            self.languages
  666                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  667        }
  668
  669        self.language_servers.insert(server_id, state);
  670        self.language_server_ids
  671            .entry(key)
  672            .or_insert(UnifiedLanguageServer {
  673                id: server_id,
  674                project_roots: Default::default(),
  675            });
  676        server_id
  677    }
  678
  679    fn get_language_server_binary(
  680        &self,
  681        worktree_abs_path: Arc<Path>,
  682        adapter: Arc<CachedLspAdapter>,
  683        settings: Arc<LspSettings>,
  684        toolchain: Option<Toolchain>,
  685        delegate: Arc<dyn LspAdapterDelegate>,
  686        allow_binary_download: bool,
  687        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  688        cx: &mut App,
  689    ) -> Task<Result<LanguageServerBinary>> {
  690        if let Some(settings) = &settings.binary
  691            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  692        {
  693            let settings = settings.clone();
  694            let languages = self.languages.clone();
  695            return cx.background_spawn(async move {
  696                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  697                    let already_trusted =  *wait_until_worktree_trust.borrow();
  698                    if !already_trusted {
  699                        log::info!(
  700                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  701                            adapter.name(),
  702                        );
  703                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  704                            if worktree_trusted {
  705                                break;
  706                            }
  707                        }
  708                        log::info!(
  709                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  710                            adapter.name(),
  711                        );
  712                    }
  713                    languages
  714                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  715                }
  716                let mut env = delegate.shell_env().await;
  717                env.extend(settings.env.unwrap_or_default());
  718
  719                Ok(LanguageServerBinary {
  720                    path: delegate.resolve_relative_path(path),
  721                    env: Some(env),
  722                    arguments: settings
  723                        .arguments
  724                        .unwrap_or_default()
  725                        .iter()
  726                        .map(Into::into)
  727                        .collect(),
  728                })
  729            });
  730        }
  731        let lsp_binary_options = LanguageServerBinaryOptions {
  732            allow_path_lookup: !settings
  733                .binary
  734                .as_ref()
  735                .and_then(|b| b.ignore_system_version)
  736                .unwrap_or_default(),
  737            allow_binary_download,
  738            pre_release: settings
  739                .fetch
  740                .as_ref()
  741                .and_then(|f| f.pre_release)
  742                .unwrap_or(false),
  743        };
  744
  745        cx.spawn(async move |cx| {
  746            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  747                let already_trusted =  *wait_until_worktree_trust.borrow();
  748                if !already_trusted {
  749                    log::info!(
  750                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  751                        adapter.name(),
  752                    );
  753                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  754                        if worktree_trusted {
  755                            break;
  756                        }
  757                    }
  758                    log::info!(
  759                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  760                            adapter.name(),
  761                    );
  762                }
  763            }
  764
  765            let (existing_binary, maybe_download_binary) = adapter
  766                .clone()
  767                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  768                .await
  769                .await;
  770
  771            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  772
  773            let mut binary = match (existing_binary, maybe_download_binary) {
  774                (binary, None) => binary?,
  775                (Err(_), Some(downloader)) => downloader.await?,
  776                (Ok(existing_binary), Some(downloader)) => {
  777                    let mut download_timeout = cx
  778                        .background_executor()
  779                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  780                        .fuse();
  781                    let mut downloader = downloader.fuse();
  782                    futures::select! {
  783                        _ = download_timeout => {
  784                            // Return existing binary and kick the existing work to the background.
  785                            cx.spawn(async move |_| downloader.await).detach();
  786                            Ok(existing_binary)
  787                        },
  788                        downloaded_or_existing_binary = downloader => {
  789                            // If download fails, this results in the existing binary.
  790                            downloaded_or_existing_binary
  791                        }
  792                    }?
  793                }
  794            };
  795            let mut shell_env = delegate.shell_env().await;
  796
  797            shell_env.extend(binary.env.unwrap_or_default());
  798
  799            if let Some(settings) = settings.binary.as_ref() {
  800                if let Some(arguments) = &settings.arguments {
  801                    binary.arguments = arguments.iter().map(Into::into).collect();
  802                }
  803                if let Some(env) = &settings.env {
  804                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  805                }
  806            }
  807
  808            binary.env = Some(shell_env);
  809            Ok(binary)
  810        })
  811    }
  812
  813    fn setup_lsp_messages(
  814        lsp_store: WeakEntity<LspStore>,
  815        language_server: &LanguageServer,
  816        delegate: Arc<dyn LspAdapterDelegate>,
  817        adapter: Arc<CachedLspAdapter>,
  818    ) {
  819        let name = language_server.name();
  820        let server_id = language_server.server_id();
  821        language_server
  822            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  823                let adapter = adapter.clone();
  824                let this = lsp_store.clone();
  825                move |mut params, cx| {
  826                    let adapter = adapter.clone();
  827                    if let Some(this) = this.upgrade() {
  828                        this.update(cx, |this, cx| {
  829                            adapter.process_diagnostics(&mut params, server_id);
  830
  831                            this.merge_lsp_diagnostics(
  832                                DiagnosticSourceKind::Pushed,
  833                                vec![DocumentDiagnosticsUpdate {
  834                                    server_id,
  835                                    diagnostics: params,
  836                                    result_id: None,
  837                                    disk_based_sources: Cow::Borrowed(
  838                                        &adapter.disk_based_diagnostic_sources,
  839                                    ),
  840                                    registration_id: None,
  841                                }],
  842                                |_, diagnostic, _cx| match diagnostic.source_kind {
  843                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  844                                        adapter.retain_old_diagnostic(diagnostic)
  845                                    }
  846                                    DiagnosticSourceKind::Pulled => true,
  847                                },
  848                                cx,
  849                            )
  850                            .log_err();
  851                        });
  852                    }
  853                }
  854            })
  855            .detach();
  856        language_server
  857            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  858                let adapter = adapter.adapter.clone();
  859                let delegate = delegate.clone();
  860                let this = lsp_store.clone();
  861                move |params, cx| {
  862                    let adapter = adapter.clone();
  863                    let delegate = delegate.clone();
  864                    let this = this.clone();
  865                    let mut cx = cx.clone();
  866                    async move {
  867                        let toolchain_for_id = this
  868                            .update(&mut cx, |this, _| {
  869                                this.as_local()?.language_server_ids.iter().find_map(
  870                                    |(seed, value)| {
  871                                        (value.id == server_id).then(|| seed.toolchain.clone())
  872                                    },
  873                                )
  874                            })?
  875                            .context("Expected the LSP store to be in a local mode")?;
  876
  877                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  878                        for item in &params.items {
  879                            let scope_uri = item.scope_uri.clone();
  880                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  881                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  882                            else {
  883                                // We've already queried workspace configuration of this URI.
  884                                continue;
  885                            };
  886                            let workspace_config = Self::workspace_configuration_for_adapter(
  887                                adapter.clone(),
  888                                &delegate,
  889                                toolchain_for_id.clone(),
  890                                scope_uri,
  891                                &mut cx,
  892                            )
  893                            .await?;
  894                            new_scope_uri.insert(workspace_config);
  895                        }
  896
  897                        Ok(params
  898                            .items
  899                            .into_iter()
  900                            .filter_map(|item| {
  901                                let workspace_config =
  902                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  903                                if let Some(section) = &item.section {
  904                                    Some(
  905                                        workspace_config
  906                                            .get(section)
  907                                            .cloned()
  908                                            .unwrap_or(serde_json::Value::Null),
  909                                    )
  910                                } else {
  911                                    Some(workspace_config.clone())
  912                                }
  913                            })
  914                            .collect())
  915                    }
  916                }
  917            })
  918            .detach();
  919
  920        language_server
  921            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  922                let this = lsp_store.clone();
  923                move |_, cx| {
  924                    let this = this.clone();
  925                    let cx = cx.clone();
  926                    async move {
  927                        let Some(server) =
  928                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  929                        else {
  930                            return Ok(None);
  931                        };
  932                        let root = server.workspace_folders();
  933                        Ok(Some(
  934                            root.into_iter()
  935                                .map(|uri| WorkspaceFolder {
  936                                    uri,
  937                                    name: Default::default(),
  938                                })
  939                                .collect(),
  940                        ))
  941                    }
  942                }
  943            })
  944            .detach();
  945        // Even though we don't have handling for these requests, respond to them to
  946        // avoid stalling any language server like `gopls` which waits for a response
  947        // to these requests when initializing.
  948        language_server
  949            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  950                let this = lsp_store.clone();
  951                move |params, cx| {
  952                    let this = this.clone();
  953                    let mut cx = cx.clone();
  954                    async move {
  955                        this.update(&mut cx, |this, _| {
  956                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  957                            {
  958                                status
  959                                    .progress_tokens
  960                                    .insert(ProgressToken::from_lsp(params.token));
  961                            }
  962                        })?;
  963
  964                        Ok(())
  965                    }
  966                }
  967            })
  968            .detach();
  969
  970        language_server
  971            .on_request::<lsp::request::RegisterCapability, _, _>({
  972                let lsp_store = lsp_store.clone();
  973                move |params, cx| {
  974                    let lsp_store = lsp_store.clone();
  975                    let mut cx = cx.clone();
  976                    async move {
  977                        lsp_store
  978                            .update(&mut cx, |lsp_store, cx| {
  979                                if lsp_store.as_local().is_some() {
  980                                    match lsp_store
  981                                        .register_server_capabilities(server_id, params, cx)
  982                                    {
  983                                        Ok(()) => {}
  984                                        Err(e) => {
  985                                            log::error!(
  986                                                "Failed to register server capabilities: {e:#}"
  987                                            );
  988                                        }
  989                                    };
  990                                }
  991                            })
  992                            .ok();
  993                        Ok(())
  994                    }
  995                }
  996            })
  997            .detach();
  998
  999        language_server
 1000            .on_request::<lsp::request::UnregisterCapability, _, _>({
 1001                let lsp_store = lsp_store.clone();
 1002                move |params, cx| {
 1003                    let lsp_store = lsp_store.clone();
 1004                    let mut cx = cx.clone();
 1005                    async move {
 1006                        lsp_store
 1007                            .update(&mut cx, |lsp_store, cx| {
 1008                                if lsp_store.as_local().is_some() {
 1009                                    match lsp_store
 1010                                        .unregister_server_capabilities(server_id, params, cx)
 1011                                    {
 1012                                        Ok(()) => {}
 1013                                        Err(e) => {
 1014                                            log::error!(
 1015                                                "Failed to unregister server capabilities: {e:#}"
 1016                                            );
 1017                                        }
 1018                                    }
 1019                                }
 1020                            })
 1021                            .ok();
 1022                        Ok(())
 1023                    }
 1024                }
 1025            })
 1026            .detach();
 1027
 1028        language_server
 1029            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 1030                let this = lsp_store.clone();
 1031                move |params, cx| {
 1032                    let mut cx = cx.clone();
 1033                    let this = this.clone();
 1034                    async move {
 1035                        LocalLspStore::on_lsp_workspace_edit(
 1036                            this.clone(),
 1037                            params,
 1038                            server_id,
 1039                            &mut cx,
 1040                        )
 1041                        .await
 1042                    }
 1043                }
 1044            })
 1045            .detach();
 1046
 1047        language_server
 1048            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1049                let lsp_store = lsp_store.clone();
 1050                let request_id = Arc::new(AtomicUsize::new(0));
 1051                move |(), cx| {
 1052                    let lsp_store = lsp_store.clone();
 1053                    let request_id = request_id.clone();
 1054                    let mut cx = cx.clone();
 1055                    async move {
 1056                        lsp_store
 1057                            .update(&mut cx, |lsp_store, cx| {
 1058                                let request_id =
 1059                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1060                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1061                                    server_id,
 1062                                    request_id,
 1063                                });
 1064                                lsp_store
 1065                                    .downstream_client
 1066                                    .as_ref()
 1067                                    .map(|(client, project_id)| {
 1068                                        client.send(proto::RefreshInlayHints {
 1069                                            project_id: *project_id,
 1070                                            server_id: server_id.to_proto(),
 1071                                            request_id: request_id.map(|id| id as u64),
 1072                                        })
 1073                                    })
 1074                            })?
 1075                            .transpose()?;
 1076                        Ok(())
 1077                    }
 1078                }
 1079            })
 1080            .detach();
 1081
 1082        language_server
 1083            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1084                let this = lsp_store.clone();
 1085                move |(), cx| {
 1086                    let this = this.clone();
 1087                    let mut cx = cx.clone();
 1088                    async move {
 1089                        this.update(&mut cx, |this, cx| {
 1090                            this.invalidate_code_lens();
 1091                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1092                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1093                                client.send(proto::RefreshCodeLens {
 1094                                    project_id: *project_id,
 1095                                })
 1096                            })
 1097                        })?
 1098                        .transpose()?;
 1099                        Ok(())
 1100                    }
 1101                }
 1102            })
 1103            .detach();
 1104
 1105        language_server
 1106            .on_request::<lsp::request::SemanticTokensRefresh, _, _>({
 1107                let lsp_store = lsp_store.clone();
 1108                let request_id = Arc::new(AtomicUsize::new(0));
 1109                move |(), cx| {
 1110                    let lsp_store = lsp_store.clone();
 1111                    let request_id = request_id.clone();
 1112                    let mut cx = cx.clone();
 1113                    async move {
 1114                        lsp_store
 1115                            .update(&mut cx, |lsp_store, cx| {
 1116                                let request_id =
 1117                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1118                                cx.emit(LspStoreEvent::RefreshSemanticTokens {
 1119                                    server_id,
 1120                                    request_id,
 1121                                });
 1122                                lsp_store
 1123                                    .downstream_client
 1124                                    .as_ref()
 1125                                    .map(|(client, project_id)| {
 1126                                        client.send(proto::RefreshSemanticTokens {
 1127                                            project_id: *project_id,
 1128                                            server_id: server_id.to_proto(),
 1129                                            request_id: request_id.map(|id| id as u64),
 1130                                        })
 1131                                    })
 1132                            })?
 1133                            .transpose()?;
 1134                        Ok(())
 1135                    }
 1136                }
 1137            })
 1138            .detach();
 1139
 1140        language_server
 1141            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1142                let this = lsp_store.clone();
 1143                move |(), cx| {
 1144                    let this = this.clone();
 1145                    let mut cx = cx.clone();
 1146                    async move {
 1147                        this.update(&mut cx, |lsp_store, cx| {
 1148                            lsp_store.pull_workspace_diagnostics(server_id);
 1149                            lsp_store
 1150                                .downstream_client
 1151                                .as_ref()
 1152                                .map(|(client, project_id)| {
 1153                                    client.send(proto::PullWorkspaceDiagnostics {
 1154                                        project_id: *project_id,
 1155                                        server_id: server_id.to_proto(),
 1156                                    })
 1157                                })
 1158                                .transpose()?;
 1159                            anyhow::Ok(
 1160                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1161                            )
 1162                        })??
 1163                        .await;
 1164                        Ok(())
 1165                    }
 1166                }
 1167            })
 1168            .detach();
 1169
 1170        language_server
 1171            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1172                let this = lsp_store.clone();
 1173                let name = name.to_string();
 1174                let adapter = adapter.clone();
 1175                move |params, cx| {
 1176                    let this = this.clone();
 1177                    let name = name.to_string();
 1178                    let adapter = adapter.clone();
 1179                    let mut cx = cx.clone();
 1180                    async move {
 1181                        let actions = params.actions.unwrap_or_default();
 1182                        let message = params.message.clone();
 1183                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1184                        let level = match params.typ {
 1185                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1186                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1187                            _ => PromptLevel::Info,
 1188                        };
 1189                        let request = LanguageServerPromptRequest::new(
 1190                            level,
 1191                            params.message,
 1192                            actions,
 1193                            name.clone(),
 1194                            tx,
 1195                        );
 1196
 1197                        let did_update = this
 1198                            .update(&mut cx, |_, cx| {
 1199                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1200                            })
 1201                            .is_ok();
 1202                        if did_update {
 1203                            let response = rx.recv().await.ok();
 1204                            if let Some(ref selected_action) = response {
 1205                                let context = language::PromptResponseContext {
 1206                                    message,
 1207                                    selected_action: selected_action.clone(),
 1208                                };
 1209                                adapter.process_prompt_response(&context, &mut cx)
 1210                            }
 1211
 1212                            Ok(response)
 1213                        } else {
 1214                            Ok(None)
 1215                        }
 1216                    }
 1217                }
 1218            })
 1219            .detach();
 1220        language_server
 1221            .on_notification::<lsp::notification::ShowMessage, _>({
 1222                let this = lsp_store.clone();
 1223                let name = name.to_string();
 1224                move |params, cx| {
 1225                    let this = this.clone();
 1226                    let name = name.to_string();
 1227                    let mut cx = cx.clone();
 1228
 1229                    let (tx, _) = smol::channel::bounded(1);
 1230                    let level = match params.typ {
 1231                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1232                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1233                        _ => PromptLevel::Info,
 1234                    };
 1235                    let request =
 1236                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1237
 1238                    let _ = this.update(&mut cx, |_, cx| {
 1239                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1240                    });
 1241                }
 1242            })
 1243            .detach();
 1244
 1245        let disk_based_diagnostics_progress_token =
 1246            adapter.disk_based_diagnostics_progress_token.clone();
 1247
 1248        language_server
 1249            .on_notification::<lsp::notification::Progress, _>({
 1250                let this = lsp_store.clone();
 1251                move |params, cx| {
 1252                    if let Some(this) = this.upgrade() {
 1253                        this.update(cx, |this, cx| {
 1254                            this.on_lsp_progress(
 1255                                params,
 1256                                server_id,
 1257                                disk_based_diagnostics_progress_token.clone(),
 1258                                cx,
 1259                            );
 1260                        });
 1261                    }
 1262                }
 1263            })
 1264            .detach();
 1265
 1266        language_server
 1267            .on_notification::<lsp::notification::LogMessage, _>({
 1268                let this = lsp_store.clone();
 1269                move |params, cx| {
 1270                    if let Some(this) = this.upgrade() {
 1271                        this.update(cx, |_, cx| {
 1272                            cx.emit(LspStoreEvent::LanguageServerLog(
 1273                                server_id,
 1274                                LanguageServerLogType::Log(params.typ),
 1275                                params.message,
 1276                            ));
 1277                        });
 1278                    }
 1279                }
 1280            })
 1281            .detach();
 1282
 1283        language_server
 1284            .on_notification::<lsp::notification::LogTrace, _>({
 1285                let this = lsp_store.clone();
 1286                move |params, cx| {
 1287                    let mut cx = cx.clone();
 1288                    if let Some(this) = this.upgrade() {
 1289                        this.update(&mut cx, |_, cx| {
 1290                            cx.emit(LspStoreEvent::LanguageServerLog(
 1291                                server_id,
 1292                                LanguageServerLogType::Trace {
 1293                                    verbose_info: params.verbose,
 1294                                },
 1295                                params.message,
 1296                            ));
 1297                        });
 1298                    }
 1299                }
 1300            })
 1301            .detach();
 1302
 1303        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1304        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1305        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1306        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1307    }
 1308
 1309    fn shutdown_language_servers_on_quit(&mut self) -> impl Future<Output = ()> + use<> {
 1310        let shutdown_futures = self
 1311            .language_servers
 1312            .drain()
 1313            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1314            .collect::<Vec<_>>();
 1315
 1316        async move {
 1317            join_all(shutdown_futures).await;
 1318        }
 1319    }
 1320
 1321    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1322        match server_state {
 1323            LanguageServerState::Running { server, .. } => {
 1324                if let Some(shutdown) = server.shutdown() {
 1325                    shutdown.await;
 1326                }
 1327            }
 1328            LanguageServerState::Starting { startup, .. } => {
 1329                if let Some(server) = startup.await
 1330                    && let Some(shutdown) = server.shutdown()
 1331                {
 1332                    shutdown.await;
 1333                }
 1334            }
 1335        }
 1336        Ok(())
 1337    }
 1338
 1339    fn language_servers_for_worktree(
 1340        &self,
 1341        worktree_id: WorktreeId,
 1342    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1343        self.language_server_ids
 1344            .iter()
 1345            .filter_map(move |(seed, state)| {
 1346                if seed.worktree_id != worktree_id {
 1347                    return None;
 1348                }
 1349
 1350                if let Some(LanguageServerState::Running { server, .. }) =
 1351                    self.language_servers.get(&state.id)
 1352                {
 1353                    Some(server)
 1354                } else {
 1355                    None
 1356                }
 1357            })
 1358    }
 1359
 1360    fn language_server_ids_for_project_path(
 1361        &self,
 1362        project_path: ProjectPath,
 1363        language: &Language,
 1364        cx: &mut App,
 1365    ) -> Vec<LanguageServerId> {
 1366        let Some(worktree) = self
 1367            .worktree_store
 1368            .read(cx)
 1369            .worktree_for_id(project_path.worktree_id, cx)
 1370        else {
 1371            return Vec::new();
 1372        };
 1373        let delegate: Arc<dyn ManifestDelegate> =
 1374            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1375
 1376        self.lsp_tree
 1377            .get(
 1378                project_path,
 1379                language.name(),
 1380                language.manifest(),
 1381                &delegate,
 1382                cx,
 1383            )
 1384            .collect::<Vec<_>>()
 1385    }
 1386
 1387    fn language_server_ids_for_buffer(
 1388        &self,
 1389        buffer: &Buffer,
 1390        cx: &mut App,
 1391    ) -> Vec<LanguageServerId> {
 1392        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1393            let worktree_id = file.worktree_id(cx);
 1394
 1395            let path: Arc<RelPath> = file
 1396                .path()
 1397                .parent()
 1398                .map(Arc::from)
 1399                .unwrap_or_else(|| file.path().clone());
 1400            let worktree_path = ProjectPath { worktree_id, path };
 1401            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1402        } else {
 1403            Vec::new()
 1404        }
 1405    }
 1406
 1407    fn language_servers_for_buffer<'a>(
 1408        &'a self,
 1409        buffer: &'a Buffer,
 1410        cx: &'a mut App,
 1411    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1412        self.language_server_ids_for_buffer(buffer, cx)
 1413            .into_iter()
 1414            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1415                LanguageServerState::Running {
 1416                    adapter, server, ..
 1417                } => Some((adapter, server)),
 1418                _ => None,
 1419            })
 1420    }
 1421
 1422    async fn execute_code_action_kind_locally(
 1423        lsp_store: WeakEntity<LspStore>,
 1424        mut buffers: Vec<Entity<Buffer>>,
 1425        kind: CodeActionKind,
 1426        push_to_history: bool,
 1427        cx: &mut AsyncApp,
 1428    ) -> anyhow::Result<ProjectTransaction> {
 1429        // Do not allow multiple concurrent code actions requests for the
 1430        // same buffer.
 1431        lsp_store.update(cx, |this, cx| {
 1432            let this = this.as_local_mut().unwrap();
 1433            buffers.retain(|buffer| {
 1434                this.buffers_being_formatted
 1435                    .insert(buffer.read(cx).remote_id())
 1436            });
 1437        })?;
 1438        let _cleanup = defer({
 1439            let this = lsp_store.clone();
 1440            let mut cx = cx.clone();
 1441            let buffers = &buffers;
 1442            move || {
 1443                this.update(&mut cx, |this, cx| {
 1444                    let this = this.as_local_mut().unwrap();
 1445                    for buffer in buffers {
 1446                        this.buffers_being_formatted
 1447                            .remove(&buffer.read(cx).remote_id());
 1448                    }
 1449                })
 1450                .ok();
 1451            }
 1452        });
 1453        let mut project_transaction = ProjectTransaction::default();
 1454
 1455        for buffer in &buffers {
 1456            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1457                buffer.update(cx, |buffer, cx| {
 1458                    lsp_store
 1459                        .as_local()
 1460                        .unwrap()
 1461                        .language_servers_for_buffer(buffer, cx)
 1462                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1463                        .collect::<Vec<_>>()
 1464                })
 1465            })?;
 1466            for (_, language_server) in adapters_and_servers.iter() {
 1467                let actions = Self::get_server_code_actions_from_action_kinds(
 1468                    &lsp_store,
 1469                    language_server.server_id(),
 1470                    vec![kind.clone()],
 1471                    buffer,
 1472                    cx,
 1473                )
 1474                .await?;
 1475                Self::execute_code_actions_on_server(
 1476                    &lsp_store,
 1477                    language_server,
 1478                    actions,
 1479                    push_to_history,
 1480                    &mut project_transaction,
 1481                    cx,
 1482                )
 1483                .await?;
 1484            }
 1485        }
 1486        Ok(project_transaction)
 1487    }
 1488
 1489    async fn format_locally(
 1490        lsp_store: WeakEntity<LspStore>,
 1491        mut buffers: Vec<FormattableBuffer>,
 1492        push_to_history: bool,
 1493        trigger: FormatTrigger,
 1494        logger: zlog::Logger,
 1495        cx: &mut AsyncApp,
 1496    ) -> anyhow::Result<ProjectTransaction> {
 1497        // Do not allow multiple concurrent formatting requests for the
 1498        // same buffer.
 1499        lsp_store.update(cx, |this, cx| {
 1500            let this = this.as_local_mut().unwrap();
 1501            buffers.retain(|buffer| {
 1502                this.buffers_being_formatted
 1503                    .insert(buffer.handle.read(cx).remote_id())
 1504            });
 1505        })?;
 1506
 1507        let _cleanup = defer({
 1508            let this = lsp_store.clone();
 1509            let mut cx = cx.clone();
 1510            let buffers = &buffers;
 1511            move || {
 1512                this.update(&mut cx, |this, cx| {
 1513                    let this = this.as_local_mut().unwrap();
 1514                    for buffer in buffers {
 1515                        this.buffers_being_formatted
 1516                            .remove(&buffer.handle.read(cx).remote_id());
 1517                    }
 1518                })
 1519                .ok();
 1520            }
 1521        });
 1522
 1523        let mut project_transaction = ProjectTransaction::default();
 1524
 1525        for buffer in &buffers {
 1526            zlog::debug!(
 1527                logger =>
 1528                "formatting buffer '{:?}'",
 1529                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1530            );
 1531            // Create an empty transaction to hold all of the formatting edits.
 1532            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1533                // ensure no transactions created while formatting are
 1534                // grouped with the previous transaction in the history
 1535                // based on the transaction group interval
 1536                buffer.finalize_last_transaction();
 1537                buffer
 1538                    .start_transaction()
 1539                    .context("transaction already open")?;
 1540                buffer.end_transaction(cx);
 1541                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1542                buffer.finalize_last_transaction();
 1543                anyhow::Ok(transaction_id)
 1544            })?;
 1545
 1546            let result = Self::format_buffer_locally(
 1547                lsp_store.clone(),
 1548                buffer,
 1549                formatting_transaction_id,
 1550                trigger,
 1551                logger,
 1552                cx,
 1553            )
 1554            .await;
 1555
 1556            buffer.handle.update(cx, |buffer, cx| {
 1557                let Some(formatting_transaction) =
 1558                    buffer.get_transaction(formatting_transaction_id).cloned()
 1559                else {
 1560                    zlog::warn!(logger => "no formatting transaction");
 1561                    return;
 1562                };
 1563                if formatting_transaction.edit_ids.is_empty() {
 1564                    zlog::debug!(logger => "no changes made while formatting");
 1565                    buffer.forget_transaction(formatting_transaction_id);
 1566                    return;
 1567                }
 1568                if !push_to_history {
 1569                    zlog::trace!(logger => "forgetting format transaction");
 1570                    buffer.forget_transaction(formatting_transaction.id);
 1571                }
 1572                project_transaction
 1573                    .0
 1574                    .insert(cx.entity(), formatting_transaction);
 1575            });
 1576
 1577            result?;
 1578        }
 1579
 1580        Ok(project_transaction)
 1581    }
 1582
 1583    async fn format_buffer_locally(
 1584        lsp_store: WeakEntity<LspStore>,
 1585        buffer: &FormattableBuffer,
 1586        formatting_transaction_id: clock::Lamport,
 1587        trigger: FormatTrigger,
 1588        logger: zlog::Logger,
 1589        cx: &mut AsyncApp,
 1590    ) -> Result<()> {
 1591        let (adapters_and_servers, settings, request_timeout) =
 1592            lsp_store.update(cx, |lsp_store, cx| {
 1593                buffer.handle.update(cx, |buffer, cx| {
 1594                    let adapters_and_servers = lsp_store
 1595                        .as_local()
 1596                        .unwrap()
 1597                        .language_servers_for_buffer(buffer, cx)
 1598                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1599                        .collect::<Vec<_>>();
 1600                    let settings = LanguageSettings::for_buffer(buffer, cx).into_owned();
 1601                    let request_timeout = ProjectSettings::get_global(cx)
 1602                        .global_lsp_settings
 1603                        .get_request_timeout();
 1604                    (adapters_and_servers, settings, request_timeout)
 1605                })
 1606            })?;
 1607        let had_existing_line_endings = buffer
 1608            .handle
 1609            .read_with(cx, |buffer, _| buffer.max_point().row > 0);
 1610
 1611        // handle whitespace formatting
 1612        if settings.remove_trailing_whitespace_on_save {
 1613            zlog::trace!(logger => "removing trailing whitespace");
 1614            let diff = buffer
 1615                .handle
 1616                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1617                .await;
 1618            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1619                buffer.apply_diff(diff, cx);
 1620            })?;
 1621        }
 1622
 1623        if settings.ensure_final_newline_on_save {
 1624            zlog::trace!(logger => "ensuring final newline");
 1625            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1626                buffer.ensure_final_newline(cx);
 1627            })?;
 1628        }
 1629
 1630        let line_ending_policy = match settings.line_ending {
 1631            LineEndingSetting::Detect => None,
 1632            LineEndingSetting::PreferLf => Some((LineEnding::Unix, true)),
 1633            LineEndingSetting::PreferCrlf => Some((LineEnding::Windows, true)),
 1634            LineEndingSetting::EnforceLf => Some((LineEnding::Unix, false)),
 1635            LineEndingSetting::EnforceCrlf => Some((LineEnding::Windows, false)),
 1636        };
 1637        if let Some((desired_line_ending, preserve_existing)) = line_ending_policy {
 1638            buffer.handle.update(cx, |buffer, cx| {
 1639                if buffer.line_ending() == desired_line_ending {
 1640                    return;
 1641                }
 1642                if preserve_existing && had_existing_line_endings {
 1643                    zlog::trace!(
 1644                        logger => "preserving existing line endings ({}) on save",
 1645                        buffer.line_ending().label()
 1646                    );
 1647                    return;
 1648                }
 1649                zlog::trace!(logger => "normalizing line endings to {}", desired_line_ending.label());
 1650                buffer.set_line_ending(desired_line_ending, cx);
 1651            });
 1652        }
 1653
 1654        // Formatter for `code_actions_on_format` that runs before
 1655        // the rest of the formatters
 1656        let mut code_actions_on_format_formatters = None;
 1657        let should_run_code_actions_on_format = !matches!(
 1658            (trigger, &settings.format_on_save),
 1659            (FormatTrigger::Save, &FormatOnSave::Off)
 1660        );
 1661        if should_run_code_actions_on_format {
 1662            let have_code_actions_to_run_on_format = settings
 1663                .code_actions_on_format
 1664                .values()
 1665                .any(|enabled| *enabled);
 1666            if have_code_actions_to_run_on_format {
 1667                zlog::trace!(logger => "going to run code actions on format");
 1668                code_actions_on_format_formatters = Some(
 1669                    settings
 1670                        .code_actions_on_format
 1671                        .iter()
 1672                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1673                        .cloned()
 1674                        .map(Formatter::CodeAction)
 1675                        .collect::<Vec<_>>(),
 1676                );
 1677            }
 1678        }
 1679
 1680        let formatters = match (trigger, &settings.format_on_save) {
 1681            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1682            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1683                settings.formatter.as_ref()
 1684            }
 1685        };
 1686
 1687        let formatters = code_actions_on_format_formatters
 1688            .iter()
 1689            .flatten()
 1690            .chain(formatters);
 1691
 1692        for formatter in formatters {
 1693            let formatter = if formatter == &Formatter::Auto {
 1694                if settings.prettier.allowed {
 1695                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1696                    &Formatter::Prettier
 1697                } else {
 1698                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1699                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1700                }
 1701            } else {
 1702                formatter
 1703            };
 1704            if let Err(err) = Self::apply_formatter(
 1705                formatter,
 1706                &lsp_store,
 1707                buffer,
 1708                formatting_transaction_id,
 1709                &adapters_and_servers,
 1710                &settings,
 1711                request_timeout,
 1712                logger,
 1713                cx,
 1714            )
 1715            .await
 1716            {
 1717                zlog::error!(logger => "Formatter failed, skipping: {err:#}");
 1718            }
 1719        }
 1720
 1721        Ok(())
 1722    }
 1723
 1724    async fn apply_formatter(
 1725        formatter: &Formatter,
 1726        lsp_store: &WeakEntity<LspStore>,
 1727        buffer: &FormattableBuffer,
 1728        formatting_transaction_id: clock::Lamport,
 1729        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 1730        settings: &LanguageSettings,
 1731        request_timeout: Duration,
 1732        logger: zlog::Logger,
 1733        cx: &mut AsyncApp,
 1734    ) -> anyhow::Result<()> {
 1735        match formatter {
 1736            Formatter::None => {
 1737                zlog::trace!(logger => "skipping formatter 'none'");
 1738                return Ok(());
 1739            }
 1740            Formatter::Auto => {
 1741                debug_panic!("Auto resolved above");
 1742                return Ok(());
 1743            }
 1744            Formatter::Prettier => {
 1745                let logger = zlog::scoped!(logger => "prettier");
 1746                zlog::trace!(logger => "formatting");
 1747                let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1748
 1749                // When selection ranges are provided (via FormatSelections), we pass the
 1750                // encompassing UTF-16 range to Prettier so it can scope its formatting.
 1751                // After diffing, we filter the resulting edits to only keep those that
 1752                // overlap with the original byte-level selection ranges.
 1753                let (range_utf16, byte_ranges) = match buffer.ranges.as_ref() {
 1754                    Some(ranges) if !ranges.is_empty() => {
 1755                        let (utf16_range, byte_ranges) =
 1756                            buffer.handle.read_with(cx, |buffer, _cx| {
 1757                                let snapshot = buffer.snapshot();
 1758                                let mut min_start_utf16 = OffsetUtf16(usize::MAX);
 1759                                let mut max_end_utf16 = OffsetUtf16(0);
 1760                                let mut byte_ranges = Vec::with_capacity(ranges.len());
 1761                                for range in ranges {
 1762                                    let start_utf16 = range.start.to_offset_utf16(&snapshot);
 1763                                    let end_utf16 = range.end.to_offset_utf16(&snapshot);
 1764                                    min_start_utf16.0 = min_start_utf16.0.min(start_utf16.0);
 1765                                    max_end_utf16.0 = max_end_utf16.0.max(end_utf16.0);
 1766
 1767                                    let start_byte = range.start.to_offset(&snapshot);
 1768                                    let end_byte = range.end.to_offset(&snapshot);
 1769                                    byte_ranges.push(start_byte..end_byte);
 1770                                }
 1771                                (min_start_utf16..max_end_utf16, byte_ranges)
 1772                            });
 1773                        (Some(utf16_range), Some(byte_ranges))
 1774                    }
 1775                    _ => (None, None),
 1776                };
 1777
 1778                let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1779                    lsp_store.prettier_store().unwrap().downgrade()
 1780                })?;
 1781                let diff = prettier_store::format_with_prettier(
 1782                    &prettier,
 1783                    &buffer.handle,
 1784                    range_utf16,
 1785                    cx,
 1786                )
 1787                .await
 1788                .transpose()?;
 1789                let Some(mut diff) = diff else {
 1790                    zlog::trace!(logger => "No changes");
 1791                    return Ok(());
 1792                };
 1793
 1794                if let Some(byte_ranges) = byte_ranges {
 1795                    diff.edits.retain(|(edit_range, _)| {
 1796                        byte_ranges.iter().any(|selection_range| {
 1797                            edit_range.start < selection_range.end
 1798                                && edit_range.end > selection_range.start
 1799                        })
 1800                    });
 1801                    if diff.edits.is_empty() {
 1802                        zlog::trace!(logger => "No changes within selection");
 1803                        return Ok(());
 1804                    }
 1805                }
 1806
 1807                extend_formatting_transaction(
 1808                    buffer,
 1809                    formatting_transaction_id,
 1810                    cx,
 1811                    |buffer, cx| {
 1812                        buffer.apply_diff(diff, cx);
 1813                    },
 1814                )?;
 1815            }
 1816            Formatter::External { command, arguments } => {
 1817                let logger = zlog::scoped!(logger => "command");
 1818
 1819                if buffer.ranges.is_some() {
 1820                    zlog::debug!(logger => "External formatter does not support range formatting; skipping");
 1821                    return Ok(());
 1822                }
 1823
 1824                zlog::trace!(logger => "formatting");
 1825                let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1826
 1827                let diff =
 1828                    Self::format_via_external_command(buffer, &command, arguments.as_deref(), cx)
 1829                        .await
 1830                        .with_context(|| {
 1831                            format!("Failed to format buffer via external command: {}", command)
 1832                        })?;
 1833                let Some(diff) = diff else {
 1834                    zlog::trace!(logger => "No changes");
 1835                    return Ok(());
 1836                };
 1837
 1838                extend_formatting_transaction(
 1839                    buffer,
 1840                    formatting_transaction_id,
 1841                    cx,
 1842                    |buffer, cx| {
 1843                        buffer.apply_diff(diff, cx);
 1844                    },
 1845                )?;
 1846            }
 1847            Formatter::LanguageServer(specifier) => {
 1848                let logger = zlog::scoped!(logger => "language-server");
 1849                zlog::trace!(logger => "formatting");
 1850                let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1851
 1852                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1853                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1854                    return Ok(());
 1855                };
 1856
 1857                let language_server = match specifier {
 1858                    settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1859                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1860                            if adapter.name.0.as_ref() == name {
 1861                                Some(server.clone())
 1862                            } else {
 1863                                None
 1864                            }
 1865                        })
 1866                    }
 1867                    settings::LanguageServerFormatterSpecifier::Current => adapters_and_servers
 1868                        .iter()
 1869                        .find(|(_, server)| Self::server_supports_formatting(server))
 1870                        .map(|(_, server)| server.clone()),
 1871                };
 1872
 1873                let Some(language_server) = language_server else {
 1874                    log::debug!(
 1875                        "No language server found to format buffer '{:?}'. Skipping",
 1876                        buffer_path_abs.as_path().to_string_lossy()
 1877                    );
 1878                    return Ok(());
 1879                };
 1880
 1881                zlog::trace!(
 1882                    logger =>
 1883                    "Formatting buffer '{:?}' using language server '{:?}'",
 1884                    buffer_path_abs.as_path().to_string_lossy(),
 1885                    language_server.name()
 1886                );
 1887
 1888                let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1889                    zlog::trace!(logger => "formatting ranges");
 1890                    Self::format_ranges_via_lsp(
 1891                        &lsp_store,
 1892                        &buffer.handle,
 1893                        ranges,
 1894                        buffer_path_abs,
 1895                        &language_server,
 1896                        &settings,
 1897                        cx,
 1898                    )
 1899                    .await
 1900                    .context("Failed to format ranges via language server")?
 1901                } else {
 1902                    zlog::trace!(logger => "formatting full");
 1903                    Self::format_via_lsp(
 1904                        &lsp_store,
 1905                        &buffer.handle,
 1906                        buffer_path_abs,
 1907                        &language_server,
 1908                        &settings,
 1909                        cx,
 1910                    )
 1911                    .await
 1912                    .context("failed to format via language server")?
 1913                };
 1914
 1915                if edits.is_empty() {
 1916                    zlog::trace!(logger => "No changes");
 1917                    return Ok(());
 1918                }
 1919                extend_formatting_transaction(
 1920                    buffer,
 1921                    formatting_transaction_id,
 1922                    cx,
 1923                    |buffer, cx| {
 1924                        buffer.edit(edits, None, cx);
 1925                    },
 1926                )?;
 1927            }
 1928            Formatter::CodeAction(code_action_name) => {
 1929                let logger = zlog::scoped!(logger => "code-actions");
 1930                zlog::trace!(logger => "formatting");
 1931                let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1932
 1933                let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1934                    zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1935                    return Ok(());
 1936                };
 1937
 1938                let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1939                zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1940
 1941                let mut actions_and_servers = Vec::new();
 1942
 1943                for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1944                    let actions_result = Self::get_server_code_actions_from_action_kinds(
 1945                        &lsp_store,
 1946                        language_server.server_id(),
 1947                        vec![code_action_kind.clone()],
 1948                        &buffer.handle,
 1949                        cx,
 1950                    )
 1951                    .await
 1952                    .with_context(|| {
 1953                        format!(
 1954                            "Failed to resolve code action {:?} with language server {}",
 1955                            code_action_kind,
 1956                            language_server.name()
 1957                        )
 1958                    });
 1959                    let Ok(actions) = actions_result else {
 1960                        // note: it may be better to set result to the error and break formatters here
 1961                        // but for now we try to execute the actions that we can resolve and skip the rest
 1962                        zlog::error!(
 1963                            logger =>
 1964                            "Failed to resolve code action {:?} with language server {}",
 1965                            code_action_kind,
 1966                            language_server.name()
 1967                        );
 1968                        continue;
 1969                    };
 1970                    for action in actions {
 1971                        actions_and_servers.push((action, index));
 1972                    }
 1973                }
 1974
 1975                if actions_and_servers.is_empty() {
 1976                    zlog::warn!(logger => "No code actions were resolved, continuing");
 1977                    return Ok(());
 1978                }
 1979
 1980                'actions: for (mut action, server_index) in actions_and_servers {
 1981                    let server = &adapters_and_servers[server_index].1;
 1982
 1983                    let describe_code_action = |action: &CodeAction| {
 1984                        format!(
 1985                            "code action '{}' with title \"{}\" on server {}",
 1986                            action
 1987                                .lsp_action
 1988                                .action_kind()
 1989                                .unwrap_or("unknown".into())
 1990                                .as_str(),
 1991                            action.lsp_action.title(),
 1992                            server.name(),
 1993                        )
 1994                    };
 1995
 1996                    zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1997
 1998                    if let Err(err) =
 1999                        Self::try_resolve_code_action(server, &mut action, request_timeout).await
 2000                    {
 2001                        zlog::error!(
 2002                            logger =>
 2003                            "Failed to resolve {}. Error: {}",
 2004                            describe_code_action(&action),
 2005                            err
 2006                        );
 2007                        continue;
 2008                    }
 2009
 2010                    if let Some(edit) = action.lsp_action.edit().cloned() {
 2011                        // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 2012                        // but filters out and logs warnings for code actions that require unreasonably
 2013                        // difficult handling on our part, such as:
 2014                        // - applying edits that call commands
 2015                        //   which can result in arbitrary workspace edits being sent from the server that
 2016                        //   have no way of being tied back to the command that initiated them (i.e. we
 2017                        //   can't know which edits are part of the format request, or if the server is done sending
 2018                        //   actions in response to the command)
 2019                        // - actions that create/delete/modify/rename files other than the one we are formatting
 2020                        //   as we then would need to handle such changes correctly in the local history as well
 2021                        //   as the remote history through the ProjectTransaction
 2022                        // - actions with snippet edits, as these simply don't make sense in the context of a format request
 2023                        // Supporting these actions is not impossible, but not supported as of yet.
 2024                        if edit.changes.is_none() && edit.document_changes.is_none() {
 2025                            zlog::trace!(
 2026                                logger =>
 2027                                "No changes for code action. Skipping {}",
 2028                                describe_code_action(&action),
 2029                            );
 2030                            continue;
 2031                        }
 2032
 2033                        let mut operations = Vec::new();
 2034                        if let Some(document_changes) = edit.document_changes {
 2035                            match document_changes {
 2036                                lsp::DocumentChanges::Edits(edits) => operations.extend(
 2037                                    edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 2038                                ),
 2039                                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2040                            }
 2041                        } else if let Some(changes) = edit.changes {
 2042                            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2043                                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2044                                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2045                                        uri,
 2046                                        version: None,
 2047                                    },
 2048                                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2049                                })
 2050                            }));
 2051                        }
 2052
 2053                        let mut edits = Vec::with_capacity(operations.len());
 2054
 2055                        if operations.is_empty() {
 2056                            zlog::trace!(
 2057                                logger =>
 2058                                "No changes for code action. Skipping {}",
 2059                                describe_code_action(&action),
 2060                            );
 2061                            continue;
 2062                        }
 2063                        for operation in operations {
 2064                            let op = match operation {
 2065                                lsp::DocumentChangeOperation::Edit(op) => op,
 2066                                lsp::DocumentChangeOperation::Op(_) => {
 2067                                    zlog::warn!(
 2068                                        logger =>
 2069                                        "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 2070                                        describe_code_action(&action),
 2071                                    );
 2072                                    continue 'actions;
 2073                                }
 2074                            };
 2075                            let Ok(file_path) = op.text_document.uri.to_file_path() else {
 2076                                zlog::warn!(
 2077                                    logger =>
 2078                                    "Failed to convert URI '{:?}' to file path. Skipping {}",
 2079                                    &op.text_document.uri,
 2080                                    describe_code_action(&action),
 2081                                );
 2082                                continue 'actions;
 2083                            };
 2084                            if &file_path != buffer_path_abs {
 2085                                zlog::warn!(
 2086                                    logger =>
 2087                                    "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 2088                                    file_path,
 2089                                    buffer_path_abs,
 2090                                    describe_code_action(&action),
 2091                                );
 2092                                continue 'actions;
 2093                            }
 2094
 2095                            let mut lsp_edits = Vec::new();
 2096                            for edit in op.edits {
 2097                                match edit {
 2098                                    Edit::Plain(edit) => {
 2099                                        if !lsp_edits.contains(&edit) {
 2100                                            lsp_edits.push(edit);
 2101                                        }
 2102                                    }
 2103                                    Edit::Annotated(edit) => {
 2104                                        if !lsp_edits.contains(&edit.text_edit) {
 2105                                            lsp_edits.push(edit.text_edit);
 2106                                        }
 2107                                    }
 2108                                    Edit::Snippet(_) => {
 2109                                        zlog::warn!(
 2110                                            logger =>
 2111                                            "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 2112                                            describe_code_action(&action),
 2113                                        );
 2114                                        continue 'actions;
 2115                                    }
 2116                                }
 2117                            }
 2118                            let edits_result = lsp_store
 2119                                .update(cx, |lsp_store, cx| {
 2120                                    lsp_store.as_local_mut().unwrap().edits_from_lsp(
 2121                                        &buffer.handle,
 2122                                        lsp_edits,
 2123                                        server.server_id(),
 2124                                        op.text_document.version,
 2125                                        cx,
 2126                                    )
 2127                                })?
 2128                                .await;
 2129                            let Ok(resolved_edits) = edits_result else {
 2130                                zlog::warn!(
 2131                                    logger =>
 2132                                    "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 2133                                    buffer_path_abs.as_path(),
 2134                                    describe_code_action(&action),
 2135                                );
 2136                                continue 'actions;
 2137                            };
 2138                            edits.extend(resolved_edits);
 2139                        }
 2140
 2141                        if edits.is_empty() {
 2142                            zlog::warn!(logger => "No edits resolved from LSP");
 2143                            continue;
 2144                        }
 2145
 2146                        extend_formatting_transaction(
 2147                            buffer,
 2148                            formatting_transaction_id,
 2149                            cx,
 2150                            |buffer, cx| {
 2151                                zlog::info!(
 2152                                    "Applying edits {edits:?}. Content: {:?}",
 2153                                    buffer.text()
 2154                                );
 2155                                buffer.edit(edits, None, cx);
 2156                                zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 2157                            },
 2158                        )?;
 2159                    }
 2160
 2161                    let Some(command) = action.lsp_action.command() else {
 2162                        continue;
 2163                    };
 2164
 2165                    zlog::warn!(
 2166                        logger =>
 2167                        "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 2168                        &command.command,
 2169                    );
 2170
 2171                    let server_capabilities = server.capabilities();
 2172                    let available_commands = server_capabilities
 2173                        .execute_command_provider
 2174                        .as_ref()
 2175                        .map(|options| options.commands.as_slice())
 2176                        .unwrap_or_default();
 2177                    if !available_commands.contains(&command.command) {
 2178                        zlog::warn!(
 2179                            logger =>
 2180                            "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2181                            command.command,
 2182                            server.name(),
 2183                        );
 2184                        continue;
 2185                    }
 2186
 2187                    extend_formatting_transaction(
 2188                        buffer,
 2189                        formatting_transaction_id,
 2190                        cx,
 2191                        |_, _| {},
 2192                    )?;
 2193                    zlog::info!(logger => "Executing command {}", &command.command);
 2194
 2195                    lsp_store.update(cx, |this, _| {
 2196                        this.as_local_mut()
 2197                            .unwrap()
 2198                            .last_workspace_edits_by_language_server
 2199                            .remove(&server.server_id());
 2200                    })?;
 2201
 2202                    let execute_command_result = server
 2203                        .request::<lsp::request::ExecuteCommand>(
 2204                            lsp::ExecuteCommandParams {
 2205                                command: command.command.clone(),
 2206                                arguments: command.arguments.clone().unwrap_or_default(),
 2207                                ..Default::default()
 2208                            },
 2209                            request_timeout,
 2210                        )
 2211                        .await
 2212                        .into_response();
 2213
 2214                    if execute_command_result.is_err() {
 2215                        zlog::error!(
 2216                            logger =>
 2217                            "Failed to execute command '{}' as part of {}",
 2218                            &command.command,
 2219                            describe_code_action(&action),
 2220                        );
 2221                        continue 'actions;
 2222                    }
 2223
 2224                    let mut project_transaction_command = lsp_store.update(cx, |this, _| {
 2225                        this.as_local_mut()
 2226                            .unwrap()
 2227                            .last_workspace_edits_by_language_server
 2228                            .remove(&server.server_id())
 2229                            .unwrap_or_default()
 2230                    })?;
 2231
 2232                    if let Some(transaction) = project_transaction_command.0.remove(&buffer.handle)
 2233                    {
 2234                        zlog::trace!(
 2235                            logger =>
 2236                            "Successfully captured {} edits that resulted from command {}",
 2237                            transaction.edit_ids.len(),
 2238                            &command.command,
 2239                        );
 2240                        let transaction_id_project_transaction = transaction.id;
 2241                        buffer.handle.update(cx, |buffer, _| {
 2242                            // it may have been removed from history if push_to_history was
 2243                            // false in deserialize_workspace_edit. If so push it so we
 2244                            // can merge it with the format transaction
 2245                            // and pop the combined transaction off the history stack
 2246                            // later if push_to_history is false
 2247                            if buffer.get_transaction(transaction.id).is_none() {
 2248                                buffer.push_transaction(transaction, Instant::now());
 2249                            }
 2250                            buffer.merge_transactions(
 2251                                transaction_id_project_transaction,
 2252                                formatting_transaction_id,
 2253                            );
 2254                        });
 2255                    }
 2256
 2257                    if project_transaction_command.0.is_empty() {
 2258                        continue;
 2259                    }
 2260
 2261                    let mut extra_buffers = String::new();
 2262                    for buffer in project_transaction_command.0.keys() {
 2263                        buffer.read_with(cx, |b, cx| {
 2264                            let Some(path) = b.project_path(cx) else {
 2265                                return;
 2266                            };
 2267
 2268                            if !extra_buffers.is_empty() {
 2269                                extra_buffers.push_str(", ");
 2270                            }
 2271                            extra_buffers.push_str(path.path.as_unix_str());
 2272                        });
 2273                    }
 2274                    zlog::warn!(
 2275                        logger =>
 2276                        "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2277                        &command.command,
 2278                        extra_buffers,
 2279                    );
 2280                    // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2281                    // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2282                    // add it so it's included, and merge it into the format transaction when its created later
 2283                }
 2284            }
 2285        }
 2286
 2287        Ok(())
 2288    }
 2289
 2290    pub async fn format_ranges_via_lsp(
 2291        this: &WeakEntity<LspStore>,
 2292        buffer_handle: &Entity<Buffer>,
 2293        ranges: &[Range<Anchor>],
 2294        abs_path: &Path,
 2295        language_server: &Arc<LanguageServer>,
 2296        settings: &LanguageSettings,
 2297        cx: &mut AsyncApp,
 2298    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2299        let capabilities = &language_server.capabilities();
 2300        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2301        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2302            anyhow::bail!(
 2303                "{} language server does not support range formatting",
 2304                language_server.name()
 2305            );
 2306        }
 2307
 2308        let uri = file_path_to_lsp_url(abs_path)?;
 2309        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2310
 2311        let request_timeout = cx.update(|app| {
 2312            ProjectSettings::get_global(app)
 2313                .global_lsp_settings
 2314                .get_request_timeout()
 2315        });
 2316        let lsp_edits = {
 2317            let mut lsp_ranges = Vec::new();
 2318            this.update(cx, |_this, cx| {
 2319                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2320                // not have been sent to the language server. This seems like a fairly systemic
 2321                // issue, though, the resolution probably is not specific to formatting.
 2322                //
 2323                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2324                // LSP.
 2325                let snapshot = buffer_handle.read(cx).snapshot();
 2326                for range in ranges {
 2327                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2328                }
 2329                anyhow::Ok(())
 2330            })??;
 2331
 2332            let mut edits = None;
 2333            for range in lsp_ranges {
 2334                if let Some(mut edit) = language_server
 2335                    .request::<lsp::request::RangeFormatting>(
 2336                        lsp::DocumentRangeFormattingParams {
 2337                            text_document: text_document.clone(),
 2338                            range,
 2339                            options: lsp_command::lsp_formatting_options(settings),
 2340                            work_done_progress_params: Default::default(),
 2341                        },
 2342                        request_timeout,
 2343                    )
 2344                    .await
 2345                    .into_response()?
 2346                {
 2347                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2348                }
 2349            }
 2350            edits
 2351        };
 2352
 2353        if let Some(lsp_edits) = lsp_edits {
 2354            this.update(cx, |this, cx| {
 2355                this.as_local_mut().unwrap().edits_from_lsp(
 2356                    buffer_handle,
 2357                    lsp_edits,
 2358                    language_server.server_id(),
 2359                    None,
 2360                    cx,
 2361                )
 2362            })?
 2363            .await
 2364        } else {
 2365            Ok(Vec::with_capacity(0))
 2366        }
 2367    }
 2368
 2369    fn server_supports_formatting(server: &Arc<LanguageServer>) -> bool {
 2370        let capabilities = server.capabilities();
 2371        let formatting = capabilities.document_formatting_provider.as_ref();
 2372        matches!(formatting, Some(p) if *p != OneOf::Left(false))
 2373            || server_capabilities_support_range_formatting(&capabilities)
 2374    }
 2375
 2376    async fn format_via_lsp(
 2377        this: &WeakEntity<LspStore>,
 2378        buffer: &Entity<Buffer>,
 2379        abs_path: &Path,
 2380        language_server: &Arc<LanguageServer>,
 2381        settings: &LanguageSettings,
 2382        cx: &mut AsyncApp,
 2383    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2384        let logger = zlog::scoped!("lsp_format");
 2385        zlog::debug!(logger => "Formatting via LSP");
 2386
 2387        let uri = file_path_to_lsp_url(abs_path)?;
 2388        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2389        let capabilities = &language_server.capabilities();
 2390
 2391        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2392        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2393
 2394        let request_timeout = cx.update(|app| {
 2395            ProjectSettings::get_global(app)
 2396                .global_lsp_settings
 2397                .get_request_timeout()
 2398        });
 2399
 2400        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2401            let _timer = zlog::time!(logger => "format-full");
 2402            language_server
 2403                .request::<lsp::request::Formatting>(
 2404                    lsp::DocumentFormattingParams {
 2405                        text_document,
 2406                        options: lsp_command::lsp_formatting_options(settings),
 2407                        work_done_progress_params: Default::default(),
 2408                    },
 2409                    request_timeout,
 2410                )
 2411                .await
 2412                .into_response()?
 2413        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2414            let _timer = zlog::time!(logger => "format-range");
 2415            let buffer_start = lsp::Position::new(0, 0);
 2416            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2417            language_server
 2418                .request::<lsp::request::RangeFormatting>(
 2419                    lsp::DocumentRangeFormattingParams {
 2420                        text_document: text_document.clone(),
 2421                        range: lsp::Range::new(buffer_start, buffer_end),
 2422                        options: lsp_command::lsp_formatting_options(settings),
 2423                        work_done_progress_params: Default::default(),
 2424                    },
 2425                    request_timeout,
 2426                )
 2427                .await
 2428                .into_response()?
 2429        } else {
 2430            None
 2431        };
 2432
 2433        if let Some(lsp_edits) = lsp_edits {
 2434            this.update(cx, |this, cx| {
 2435                this.as_local_mut().unwrap().edits_from_lsp(
 2436                    buffer,
 2437                    lsp_edits,
 2438                    language_server.server_id(),
 2439                    None,
 2440                    cx,
 2441                )
 2442            })?
 2443            .await
 2444        } else {
 2445            Ok(Vec::with_capacity(0))
 2446        }
 2447    }
 2448
 2449    async fn format_via_external_command(
 2450        buffer: &FormattableBuffer,
 2451        command: &str,
 2452        arguments: Option<&[String]>,
 2453        cx: &mut AsyncApp,
 2454    ) -> Result<Option<Diff>> {
 2455        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2456            let file = File::from_dyn(buffer.file())?;
 2457            let worktree = file.worktree.read(cx);
 2458            let mut worktree_path = worktree.abs_path().to_path_buf();
 2459            if worktree.root_entry()?.is_file() {
 2460                worktree_path.pop();
 2461            }
 2462            Some(worktree_path)
 2463        });
 2464
 2465        use util::command::Stdio;
 2466        let mut child = util::command::new_command(command);
 2467
 2468        if let Some(buffer_env) = buffer.env.as_ref() {
 2469            child.envs(buffer_env);
 2470        }
 2471
 2472        if let Some(working_dir_path) = working_dir_path {
 2473            child.current_dir(working_dir_path);
 2474        }
 2475
 2476        if let Some(arguments) = arguments {
 2477            child.args(arguments.iter().map(|arg| {
 2478                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2479                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2480                } else {
 2481                    arg.replace("{buffer_path}", "Untitled")
 2482                }
 2483            }));
 2484        }
 2485
 2486        let mut child = child
 2487            .stdin(Stdio::piped())
 2488            .stdout(Stdio::piped())
 2489            .stderr(Stdio::piped())
 2490            .spawn()?;
 2491
 2492        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2493        let text = buffer
 2494            .handle
 2495            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2496        for chunk in text.chunks() {
 2497            stdin.write_all(chunk.as_bytes()).await?;
 2498        }
 2499        stdin.flush().await?;
 2500
 2501        let output = child.output().await?;
 2502        anyhow::ensure!(
 2503            output.status.success(),
 2504            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2505            output.status.code(),
 2506            String::from_utf8_lossy(&output.stdout),
 2507            String::from_utf8_lossy(&output.stderr),
 2508        );
 2509
 2510        let stdout = String::from_utf8(output.stdout)?;
 2511        Ok(Some(
 2512            buffer
 2513                .handle
 2514                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2515                .await,
 2516        ))
 2517    }
 2518
 2519    async fn try_resolve_code_action(
 2520        lang_server: &LanguageServer,
 2521        action: &mut CodeAction,
 2522        request_timeout: Duration,
 2523    ) -> anyhow::Result<()> {
 2524        match &mut action.lsp_action {
 2525            LspAction::Action(lsp_action) => {
 2526                if !action.resolved
 2527                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2528                    && lsp_action.data.is_some()
 2529                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2530                {
 2531                    **lsp_action = lang_server
 2532                        .request::<lsp::request::CodeActionResolveRequest>(
 2533                            *lsp_action.clone(),
 2534                            request_timeout,
 2535                        )
 2536                        .await
 2537                        .into_response()?;
 2538                }
 2539            }
 2540            LspAction::CodeLens(lens) => {
 2541                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2542                    *lens = lang_server
 2543                        .request::<lsp::request::CodeLensResolve>(lens.clone(), request_timeout)
 2544                        .await
 2545                        .into_response()?;
 2546                }
 2547            }
 2548            LspAction::Command(_) => {}
 2549        }
 2550
 2551        action.resolved = true;
 2552        anyhow::Ok(())
 2553    }
 2554
 2555    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2556        let buffer = buffer_handle.read(cx);
 2557
 2558        let file = buffer.file().cloned();
 2559
 2560        let Some(file) = File::from_dyn(file.as_ref()) else {
 2561            return;
 2562        };
 2563        if !file.is_local() {
 2564            return;
 2565        }
 2566        let path = ProjectPath::from_file(file, cx);
 2567        let worktree_id = file.worktree_id(cx);
 2568        let language = buffer.language().cloned();
 2569
 2570        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2571            for (server_id, diagnostics) in
 2572                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2573            {
 2574                self.update_buffer_diagnostics(
 2575                    buffer_handle,
 2576                    server_id,
 2577                    None,
 2578                    None,
 2579                    None,
 2580                    Vec::new(),
 2581                    diagnostics,
 2582                    cx,
 2583                )
 2584                .log_err();
 2585            }
 2586        }
 2587        let Some(language) = language else {
 2588            return;
 2589        };
 2590        let Some(snapshot) = self
 2591            .worktree_store
 2592            .read(cx)
 2593            .worktree_for_id(worktree_id, cx)
 2594            .map(|worktree| worktree.read(cx).snapshot())
 2595        else {
 2596            return;
 2597        };
 2598        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2599
 2600        for server_id in
 2601            self.lsp_tree
 2602                .get(path, language.name(), language.manifest(), &delegate, cx)
 2603        {
 2604            let server = self
 2605                .language_servers
 2606                .get(&server_id)
 2607                .and_then(|server_state| {
 2608                    if let LanguageServerState::Running { server, .. } = server_state {
 2609                        Some(server.clone())
 2610                    } else {
 2611                        None
 2612                    }
 2613                });
 2614            let server = match server {
 2615                Some(server) => server,
 2616                None => continue,
 2617            };
 2618
 2619            buffer_handle.update(cx, |buffer, cx| {
 2620                buffer.set_completion_triggers(
 2621                    server.server_id(),
 2622                    server
 2623                        .capabilities()
 2624                        .completion_provider
 2625                        .as_ref()
 2626                        .and_then(|provider| {
 2627                            provider
 2628                                .trigger_characters
 2629                                .as_ref()
 2630                                .map(|characters| characters.iter().cloned().collect())
 2631                        })
 2632                        .unwrap_or_default(),
 2633                    cx,
 2634                );
 2635            });
 2636        }
 2637    }
 2638
 2639    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2640        buffer.update(cx, |buffer, cx| {
 2641            let Some(language) = buffer.language() else {
 2642                return;
 2643            };
 2644            let path = ProjectPath {
 2645                worktree_id: old_file.worktree_id(cx),
 2646                path: old_file.path.clone(),
 2647            };
 2648            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2649                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2650                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2651            }
 2652        });
 2653    }
 2654
 2655    fn update_buffer_diagnostics(
 2656        &mut self,
 2657        buffer: &Entity<Buffer>,
 2658        server_id: LanguageServerId,
 2659        registration_id: Option<Option<SharedString>>,
 2660        result_id: Option<SharedString>,
 2661        version: Option<i32>,
 2662        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2663        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2664        cx: &mut Context<LspStore>,
 2665    ) -> Result<()> {
 2666        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2667            Ordering::Equal
 2668                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2669                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2670                .then_with(|| a.severity.cmp(&b.severity))
 2671                .then_with(|| a.message.cmp(&b.message))
 2672        }
 2673
 2674        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2675        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2676        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2677
 2678        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2679            Ordering::Equal
 2680                .then_with(|| a.range.start.cmp(&b.range.start))
 2681                .then_with(|| b.range.end.cmp(&a.range.end))
 2682                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2683        });
 2684
 2685        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2686
 2687        let edits_since_save = std::cell::LazyCell::new(|| {
 2688            let saved_version = buffer.read(cx).saved_version();
 2689            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2690        });
 2691
 2692        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2693
 2694        for (new_diagnostic, entry) in diagnostics {
 2695            let start;
 2696            let end;
 2697            if new_diagnostic && entry.diagnostic.is_disk_based {
 2698                // Some diagnostics are based on files on disk instead of buffers'
 2699                // current contents. Adjust these diagnostics' ranges to reflect
 2700                // any unsaved edits.
 2701                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2702                // and were properly adjusted on reuse.
 2703                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2704                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2705            } else {
 2706                start = entry.range.start;
 2707                end = entry.range.end;
 2708            }
 2709
 2710            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2711                ..snapshot.clip_point_utf16(end, Bias::Right);
 2712
 2713            // Expand empty ranges by one codepoint
 2714            if range.start == range.end {
 2715                // This will be go to the next boundary when being clipped
 2716                range.end.column += 1;
 2717                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2718                if range.start == range.end && range.end.column > 0 {
 2719                    range.start.column -= 1;
 2720                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2721                }
 2722            }
 2723
 2724            sanitized_diagnostics.push(DiagnosticEntry {
 2725                range,
 2726                diagnostic: entry.diagnostic,
 2727            });
 2728        }
 2729        drop(edits_since_save);
 2730
 2731        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2732        buffer.update(cx, |buffer, cx| {
 2733            if let Some(registration_id) = registration_id {
 2734                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2735                    self.buffer_pull_diagnostics_result_ids
 2736                        .entry(server_id)
 2737                        .or_default()
 2738                        .entry(registration_id)
 2739                        .or_default()
 2740                        .insert(abs_path, result_id);
 2741                }
 2742            }
 2743
 2744            buffer.update_diagnostics(server_id, set, cx)
 2745        });
 2746
 2747        Ok(())
 2748    }
 2749
 2750    fn register_language_server_for_invisible_worktree(
 2751        &mut self,
 2752        worktree: &Entity<Worktree>,
 2753        language_server_id: LanguageServerId,
 2754        cx: &mut App,
 2755    ) {
 2756        let worktree = worktree.read(cx);
 2757        let worktree_id = worktree.id();
 2758        debug_assert!(!worktree.is_visible());
 2759        let Some(mut origin_seed) = self
 2760            .language_server_ids
 2761            .iter()
 2762            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2763        else {
 2764            return;
 2765        };
 2766        origin_seed.worktree_id = worktree_id;
 2767        self.language_server_ids
 2768            .entry(origin_seed)
 2769            .or_insert_with(|| UnifiedLanguageServer {
 2770                id: language_server_id,
 2771                project_roots: Default::default(),
 2772            });
 2773    }
 2774
 2775    fn register_buffer_with_language_servers(
 2776        &mut self,
 2777        buffer_handle: &Entity<Buffer>,
 2778        only_register_servers: HashSet<LanguageServerSelector>,
 2779        cx: &mut Context<LspStore>,
 2780    ) {
 2781        let buffer = buffer_handle.read(cx);
 2782        let buffer_id = buffer.remote_id();
 2783
 2784        let Some(file) = File::from_dyn(buffer.file()) else {
 2785            return;
 2786        };
 2787        if !file.is_local() {
 2788            return;
 2789        }
 2790
 2791        let abs_path = file.abs_path(cx);
 2792        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2793            return;
 2794        };
 2795        let initial_snapshot = buffer.text_snapshot();
 2796        let worktree_id = file.worktree_id(cx);
 2797
 2798        let Some(language) = buffer.language().cloned() else {
 2799            return;
 2800        };
 2801        let path: Arc<RelPath> = file
 2802            .path()
 2803            .parent()
 2804            .map(Arc::from)
 2805            .unwrap_or_else(|| file.path().clone());
 2806        let Some(worktree) = self
 2807            .worktree_store
 2808            .read(cx)
 2809            .worktree_for_id(worktree_id, cx)
 2810        else {
 2811            return;
 2812        };
 2813        let language_name = language.name();
 2814        let (reused, delegate, servers) = self
 2815            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2816            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2817            .unwrap_or_else(|| {
 2818                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2819                let delegate: Arc<dyn ManifestDelegate> =
 2820                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2821
 2822                let servers = self
 2823                    .lsp_tree
 2824                    .walk(
 2825                        ProjectPath { worktree_id, path },
 2826                        language.name(),
 2827                        language.manifest(),
 2828                        &delegate,
 2829                        cx,
 2830                    )
 2831                    .collect::<Vec<_>>();
 2832                (false, lsp_delegate, servers)
 2833            });
 2834        let servers_and_adapters = servers
 2835            .into_iter()
 2836            .filter_map(|server_node| {
 2837                if reused && server_node.server_id().is_none() {
 2838                    return None;
 2839                }
 2840                if !only_register_servers.is_empty() {
 2841                    if let Some(server_id) = server_node.server_id()
 2842                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2843                    {
 2844                        return None;
 2845                    }
 2846                    if let Some(name) = server_node.name()
 2847                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2848                    {
 2849                        return None;
 2850                    }
 2851                }
 2852
 2853                let server_id = server_node.server_id_or_init(|disposition| {
 2854                    let path = &disposition.path;
 2855
 2856                    {
 2857                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2858
 2859                        let server_id = self.get_or_insert_language_server(
 2860                            &worktree,
 2861                            delegate.clone(),
 2862                            disposition,
 2863                            &language_name,
 2864                            cx,
 2865                        );
 2866
 2867                        if let Some(state) = self.language_servers.get(&server_id)
 2868                            && let Ok(uri) = uri
 2869                        {
 2870                            state.add_workspace_folder(uri);
 2871                        };
 2872                        server_id
 2873                    }
 2874                })?;
 2875                let server_state = self.language_servers.get(&server_id)?;
 2876                if let LanguageServerState::Running {
 2877                    server, adapter, ..
 2878                } = server_state
 2879                {
 2880                    Some((server.clone(), adapter.clone()))
 2881                } else {
 2882                    None
 2883                }
 2884            })
 2885            .collect::<Vec<_>>();
 2886        for (server, adapter) in servers_and_adapters {
 2887            buffer_handle.update(cx, |buffer, cx| {
 2888                buffer.set_completion_triggers(
 2889                    server.server_id(),
 2890                    server
 2891                        .capabilities()
 2892                        .completion_provider
 2893                        .as_ref()
 2894                        .and_then(|provider| {
 2895                            provider
 2896                                .trigger_characters
 2897                                .as_ref()
 2898                                .map(|characters| characters.iter().cloned().collect())
 2899                        })
 2900                        .unwrap_or_default(),
 2901                    cx,
 2902                );
 2903            });
 2904
 2905            let snapshot = LspBufferSnapshot {
 2906                version: 0,
 2907                snapshot: initial_snapshot.clone(),
 2908            };
 2909
 2910            let mut registered = false;
 2911            self.buffer_snapshots
 2912                .entry(buffer_id)
 2913                .or_default()
 2914                .entry(server.server_id())
 2915                .or_insert_with(|| {
 2916                    registered = true;
 2917                    server.register_buffer(
 2918                        uri.clone(),
 2919                        adapter.language_id(&language.name()),
 2920                        0,
 2921                        initial_snapshot.text(),
 2922                    );
 2923
 2924                    vec![snapshot]
 2925                });
 2926
 2927            self.buffers_opened_in_servers
 2928                .entry(buffer_id)
 2929                .or_default()
 2930                .insert(server.server_id());
 2931            if registered {
 2932                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2933                    language_server_id: server.server_id(),
 2934                    name: None,
 2935                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2936                        proto::RegisteredForBuffer {
 2937                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2938                            buffer_id: buffer_id.to_proto(),
 2939                        },
 2940                    ),
 2941                });
 2942            }
 2943        }
 2944    }
 2945
 2946    fn reuse_existing_language_server<'lang_name>(
 2947        &self,
 2948        server_tree: &LanguageServerTree,
 2949        worktree: &Entity<Worktree>,
 2950        language_name: &'lang_name LanguageName,
 2951        cx: &mut App,
 2952    ) -> Option<(
 2953        Arc<LocalLspAdapterDelegate>,
 2954        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2955    )> {
 2956        if worktree.read(cx).is_visible() {
 2957            return None;
 2958        }
 2959
 2960        let worktree_store = self.worktree_store.read(cx);
 2961        let servers = server_tree
 2962            .instances
 2963            .iter()
 2964            .filter(|(worktree_id, _)| {
 2965                worktree_store
 2966                    .worktree_for_id(**worktree_id, cx)
 2967                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2968            })
 2969            .flat_map(|(worktree_id, servers)| {
 2970                servers
 2971                    .roots
 2972                    .iter()
 2973                    .flat_map(|(_, language_servers)| language_servers)
 2974                    .map(move |(_, (server_node, server_languages))| {
 2975                        (worktree_id, server_node, server_languages)
 2976                    })
 2977                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2978                    .map(|(worktree_id, server_node, _)| {
 2979                        (
 2980                            *worktree_id,
 2981                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2982                        )
 2983                    })
 2984            })
 2985            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2986                acc.entry(worktree_id)
 2987                    .or_insert_with(Vec::new)
 2988                    .push(server_node);
 2989                acc
 2990            })
 2991            .into_values()
 2992            .max_by_key(|servers| servers.len())?;
 2993
 2994        let worktree_id = worktree.read(cx).id();
 2995        let apply = move |tree: &mut LanguageServerTree| {
 2996            for server_node in &servers {
 2997                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2998            }
 2999            servers
 3000        };
 3001
 3002        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 3003        Some((delegate, apply))
 3004    }
 3005
 3006    pub(crate) fn unregister_old_buffer_from_language_servers(
 3007        &mut self,
 3008        buffer: &Entity<Buffer>,
 3009        old_file: &File,
 3010        cx: &mut App,
 3011    ) {
 3012        let old_path = match old_file.as_local() {
 3013            Some(local) => local.abs_path(cx),
 3014            None => return,
 3015        };
 3016
 3017        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 3018            debug_panic!("{old_path:?} is not parseable as an URI");
 3019            return;
 3020        };
 3021        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 3022    }
 3023
 3024    pub(crate) fn unregister_buffer_from_language_servers(
 3025        &mut self,
 3026        buffer: &Entity<Buffer>,
 3027        file_url: &lsp::Uri,
 3028        cx: &mut App,
 3029    ) {
 3030        buffer.update(cx, |buffer, cx| {
 3031            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 3032
 3033            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 3034                if snapshots
 3035                    .as_mut()
 3036                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 3037                {
 3038                    language_server.unregister_buffer(file_url.clone());
 3039                }
 3040            }
 3041        });
 3042    }
 3043
 3044    fn buffer_snapshot_for_lsp_version(
 3045        &mut self,
 3046        buffer: &Entity<Buffer>,
 3047        server_id: LanguageServerId,
 3048        version: Option<i32>,
 3049        cx: &App,
 3050    ) -> Result<TextBufferSnapshot> {
 3051        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 3052
 3053        if let Some(version) = version {
 3054            let buffer_id = buffer.read(cx).remote_id();
 3055            let snapshots = if let Some(snapshots) = self
 3056                .buffer_snapshots
 3057                .get_mut(&buffer_id)
 3058                .and_then(|m| m.get_mut(&server_id))
 3059            {
 3060                snapshots
 3061            } else if version == 0 {
 3062                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 3063                // We detect this case and treat it as if the version was `None`.
 3064                return Ok(buffer.read(cx).text_snapshot());
 3065            } else {
 3066                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 3067            };
 3068
 3069            let found_snapshot = snapshots
 3070                    .binary_search_by_key(&version, |e| e.version)
 3071                    .map(|ix| snapshots[ix].snapshot.clone())
 3072                    .map_err(|_| {
 3073                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 3074                    })?;
 3075
 3076            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 3077            Ok(found_snapshot)
 3078        } else {
 3079            Ok((buffer.read(cx)).text_snapshot())
 3080        }
 3081    }
 3082
 3083    async fn get_server_code_actions_from_action_kinds(
 3084        lsp_store: &WeakEntity<LspStore>,
 3085        language_server_id: LanguageServerId,
 3086        code_action_kinds: Vec<lsp::CodeActionKind>,
 3087        buffer: &Entity<Buffer>,
 3088        cx: &mut AsyncApp,
 3089    ) -> Result<Vec<CodeAction>> {
 3090        let actions = lsp_store
 3091            .update(cx, move |this, cx| {
 3092                let request = GetCodeActions {
 3093                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 3094                    kinds: Some(code_action_kinds),
 3095                };
 3096                let server = LanguageServerToQuery::Other(language_server_id);
 3097                this.request_lsp(buffer.clone(), server, request, cx)
 3098            })?
 3099            .await?;
 3100        Ok(actions)
 3101    }
 3102
 3103    pub async fn execute_code_actions_on_server(
 3104        lsp_store: &WeakEntity<LspStore>,
 3105        language_server: &Arc<LanguageServer>,
 3106        actions: Vec<CodeAction>,
 3107        push_to_history: bool,
 3108        project_transaction: &mut ProjectTransaction,
 3109        cx: &mut AsyncApp,
 3110    ) -> anyhow::Result<()> {
 3111        let request_timeout = cx.update(|app| {
 3112            ProjectSettings::get_global(app)
 3113                .global_lsp_settings
 3114                .get_request_timeout()
 3115        });
 3116
 3117        for mut action in actions {
 3118            Self::try_resolve_code_action(language_server, &mut action, request_timeout)
 3119                .await
 3120                .context("resolving a formatting code action")?;
 3121
 3122            if let Some(edit) = action.lsp_action.edit() {
 3123                if edit.changes.is_none() && edit.document_changes.is_none() {
 3124                    continue;
 3125                }
 3126
 3127                let new = Self::deserialize_workspace_edit(
 3128                    lsp_store.upgrade().context("project dropped")?,
 3129                    edit.clone(),
 3130                    push_to_history,
 3131                    language_server.clone(),
 3132                    cx,
 3133                )
 3134                .await?;
 3135                project_transaction.0.extend(new.0);
 3136            }
 3137
 3138            let Some(command) = action.lsp_action.command() else {
 3139                continue;
 3140            };
 3141
 3142            let server_capabilities = language_server.capabilities();
 3143            let available_commands = server_capabilities
 3144                .execute_command_provider
 3145                .as_ref()
 3146                .map(|options| options.commands.as_slice())
 3147                .unwrap_or_default();
 3148            if !available_commands.contains(&command.command) {
 3149                log::warn!(
 3150                    "Cannot execute a command {} not listed in the language server capabilities",
 3151                    command.command
 3152                );
 3153                continue;
 3154            }
 3155
 3156            lsp_store.update(cx, |lsp_store, _| {
 3157                if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 3158                    mode.last_workspace_edits_by_language_server
 3159                        .remove(&language_server.server_id());
 3160                }
 3161            })?;
 3162
 3163            language_server
 3164                .request::<lsp::request::ExecuteCommand>(
 3165                    lsp::ExecuteCommandParams {
 3166                        command: command.command.clone(),
 3167                        arguments: command.arguments.clone().unwrap_or_default(),
 3168                        ..Default::default()
 3169                    },
 3170                    request_timeout,
 3171                )
 3172                .await
 3173                .into_response()
 3174                .context("execute command")?;
 3175
 3176            lsp_store.update(cx, |this, _| {
 3177                if let LspStoreMode::Local(mode) = &mut this.mode {
 3178                    project_transaction.0.extend(
 3179                        mode.last_workspace_edits_by_language_server
 3180                            .remove(&language_server.server_id())
 3181                            .unwrap_or_default()
 3182                            .0,
 3183                    )
 3184                }
 3185            })?;
 3186        }
 3187        Ok(())
 3188    }
 3189
 3190    pub async fn deserialize_text_edits(
 3191        this: Entity<LspStore>,
 3192        buffer_to_edit: Entity<Buffer>,
 3193        edits: Vec<lsp::TextEdit>,
 3194        push_to_history: bool,
 3195        _: Arc<CachedLspAdapter>,
 3196        language_server: Arc<LanguageServer>,
 3197        cx: &mut AsyncApp,
 3198    ) -> Result<Option<Transaction>> {
 3199        let edits = this
 3200            .update(cx, |this, cx| {
 3201                this.as_local_mut().unwrap().edits_from_lsp(
 3202                    &buffer_to_edit,
 3203                    edits,
 3204                    language_server.server_id(),
 3205                    None,
 3206                    cx,
 3207                )
 3208            })
 3209            .await?;
 3210
 3211        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3212            buffer.finalize_last_transaction();
 3213            buffer.start_transaction();
 3214            for (range, text) in edits {
 3215                buffer.edit([(range, text)], None, cx);
 3216            }
 3217
 3218            if buffer.end_transaction(cx).is_some() {
 3219                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3220                if !push_to_history {
 3221                    buffer.forget_transaction(transaction.id);
 3222                }
 3223                Some(transaction)
 3224            } else {
 3225                None
 3226            }
 3227        });
 3228
 3229        Ok(transaction)
 3230    }
 3231
 3232    #[allow(clippy::type_complexity)]
 3233    pub fn edits_from_lsp(
 3234        &mut self,
 3235        buffer: &Entity<Buffer>,
 3236        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3237        server_id: LanguageServerId,
 3238        version: Option<i32>,
 3239        cx: &mut Context<LspStore>,
 3240    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3241        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3242        cx.background_spawn(async move {
 3243            let snapshot = snapshot?;
 3244            let mut lsp_edits = lsp_edits
 3245                .into_iter()
 3246                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3247                .collect::<Vec<_>>();
 3248
 3249            lsp_edits.sort_unstable_by_key(|(range, _)| (range.start, range.end));
 3250
 3251            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3252            let mut edits = Vec::new();
 3253            while let Some((range, mut new_text)) = lsp_edits.next() {
 3254                // Clip invalid ranges provided by the language server.
 3255                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3256                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3257
 3258                // Combine any LSP edits that are adjacent.
 3259                //
 3260                // Also, combine LSP edits that are separated from each other by only
 3261                // a newline. This is important because for some code actions,
 3262                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3263                // are separated by unchanged newline characters.
 3264                //
 3265                // In order for the diffing logic below to work properly, any edits that
 3266                // cancel each other out must be combined into one.
 3267                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3268                    if next_range.start.0 > range.end {
 3269                        if next_range.start.0.row > range.end.row + 1
 3270                            || next_range.start.0.column > 0
 3271                            || snapshot.clip_point_utf16(
 3272                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3273                                Bias::Left,
 3274                            ) > range.end
 3275                        {
 3276                            break;
 3277                        }
 3278                        new_text.push('\n');
 3279                    }
 3280                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3281                    new_text.push_str(next_text);
 3282                    lsp_edits.next();
 3283                }
 3284
 3285                // For multiline edits, perform a diff of the old and new text so that
 3286                // we can identify the changes more precisely, preserving the locations
 3287                // of any anchors positioned in the unchanged regions.
 3288                if range.end.row > range.start.row {
 3289                    let offset = range.start.to_offset(&snapshot);
 3290                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3291                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3292                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3293                        (
 3294                            snapshot.anchor_after(offset + range.start)
 3295                                ..snapshot.anchor_before(offset + range.end),
 3296                            replacement,
 3297                        )
 3298                    }));
 3299                } else if range.end == range.start {
 3300                    let anchor = snapshot.anchor_after(range.start);
 3301                    edits.push((anchor..anchor, new_text.into()));
 3302                } else {
 3303                    let edit_start = snapshot.anchor_after(range.start);
 3304                    let edit_end = snapshot.anchor_before(range.end);
 3305                    edits.push((edit_start..edit_end, new_text.into()));
 3306                }
 3307            }
 3308
 3309            Ok(edits)
 3310        })
 3311    }
 3312
 3313    pub(crate) async fn deserialize_workspace_edit(
 3314        this: Entity<LspStore>,
 3315        edit: lsp::WorkspaceEdit,
 3316        push_to_history: bool,
 3317        language_server: Arc<LanguageServer>,
 3318        cx: &mut AsyncApp,
 3319    ) -> Result<ProjectTransaction> {
 3320        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3321
 3322        let mut operations = Vec::new();
 3323        if let Some(document_changes) = edit.document_changes {
 3324            match document_changes {
 3325                lsp::DocumentChanges::Edits(edits) => {
 3326                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3327                }
 3328                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3329            }
 3330        } else if let Some(changes) = edit.changes {
 3331            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3332                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3333                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3334                        uri,
 3335                        version: None,
 3336                    },
 3337                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3338                })
 3339            }));
 3340        }
 3341
 3342        let mut project_transaction = ProjectTransaction::default();
 3343        for operation in operations {
 3344            match operation {
 3345                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3346                    let abs_path = op
 3347                        .uri
 3348                        .to_file_path()
 3349                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3350
 3351                    if let Some(parent_path) = abs_path.parent() {
 3352                        fs.create_dir(parent_path).await?;
 3353                    }
 3354                    if abs_path.ends_with("/") {
 3355                        fs.create_dir(&abs_path).await?;
 3356                    } else {
 3357                        fs.create_file(
 3358                            &abs_path,
 3359                            op.options
 3360                                .map(|options| fs::CreateOptions {
 3361                                    overwrite: options.overwrite.unwrap_or(false),
 3362                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3363                                })
 3364                                .unwrap_or_default(),
 3365                        )
 3366                        .await?;
 3367                    }
 3368                }
 3369
 3370                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3371                    let source_abs_path = op
 3372                        .old_uri
 3373                        .to_file_path()
 3374                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3375                    let target_abs_path = op
 3376                        .new_uri
 3377                        .to_file_path()
 3378                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3379
 3380                    let options = fs::RenameOptions {
 3381                        overwrite: op
 3382                            .options
 3383                            .as_ref()
 3384                            .and_then(|options| options.overwrite)
 3385                            .unwrap_or(false),
 3386                        ignore_if_exists: op
 3387                            .options
 3388                            .as_ref()
 3389                            .and_then(|options| options.ignore_if_exists)
 3390                            .unwrap_or(false),
 3391                        create_parents: true,
 3392                    };
 3393
 3394                    fs.rename(&source_abs_path, &target_abs_path, options)
 3395                        .await?;
 3396                }
 3397
 3398                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3399                    let abs_path = op
 3400                        .uri
 3401                        .to_file_path()
 3402                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3403                    let options = op
 3404                        .options
 3405                        .map(|options| fs::RemoveOptions {
 3406                            recursive: options.recursive.unwrap_or(false),
 3407                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3408                        })
 3409                        .unwrap_or_default();
 3410                    if abs_path.ends_with("/") {
 3411                        fs.remove_dir(&abs_path, options).await?;
 3412                    } else {
 3413                        fs.remove_file(&abs_path, options).await?;
 3414                    }
 3415                }
 3416
 3417                lsp::DocumentChangeOperation::Edit(op) => {
 3418                    let buffer_to_edit = this
 3419                        .update(cx, |this, cx| {
 3420                            this.open_local_buffer_via_lsp(
 3421                                op.text_document.uri.clone(),
 3422                                language_server.server_id(),
 3423                                cx,
 3424                            )
 3425                        })
 3426                        .await?;
 3427
 3428                    let edits = this
 3429                        .update(cx, |this, cx| {
 3430                            let path = buffer_to_edit.read(cx).project_path(cx);
 3431                            let active_entry = this.active_entry;
 3432                            let is_active_entry = path.is_some_and(|project_path| {
 3433                                this.worktree_store
 3434                                    .read(cx)
 3435                                    .entry_for_path(&project_path, cx)
 3436                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3437                            });
 3438                            let local = this.as_local_mut().unwrap();
 3439
 3440                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3441                            for edit in op.edits {
 3442                                match edit {
 3443                                    Edit::Plain(edit) => {
 3444                                        if !edits.contains(&edit) {
 3445                                            edits.push(edit)
 3446                                        }
 3447                                    }
 3448                                    Edit::Annotated(edit) => {
 3449                                        if !edits.contains(&edit.text_edit) {
 3450                                            edits.push(edit.text_edit)
 3451                                        }
 3452                                    }
 3453                                    Edit::Snippet(edit) => {
 3454                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3455                                        else {
 3456                                            continue;
 3457                                        };
 3458
 3459                                        if is_active_entry {
 3460                                            snippet_edits.push((edit.range, snippet));
 3461                                        } else {
 3462                                            // Since this buffer is not focused, apply a normal edit.
 3463                                            let new_edit = TextEdit {
 3464                                                range: edit.range,
 3465                                                new_text: snippet.text,
 3466                                            };
 3467                                            if !edits.contains(&new_edit) {
 3468                                                edits.push(new_edit);
 3469                                            }
 3470                                        }
 3471                                    }
 3472                                }
 3473                            }
 3474                            if !snippet_edits.is_empty() {
 3475                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3476                                let version = if let Some(buffer_version) = op.text_document.version
 3477                                {
 3478                                    local
 3479                                        .buffer_snapshot_for_lsp_version(
 3480                                            &buffer_to_edit,
 3481                                            language_server.server_id(),
 3482                                            Some(buffer_version),
 3483                                            cx,
 3484                                        )
 3485                                        .ok()
 3486                                        .map(|snapshot| snapshot.version)
 3487                                } else {
 3488                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3489                                };
 3490
 3491                                let most_recent_edit =
 3492                                    version.and_then(|version| version.most_recent());
 3493                                // Check if the edit that triggered that edit has been made by this participant.
 3494
 3495                                if let Some(most_recent_edit) = most_recent_edit {
 3496                                    cx.emit(LspStoreEvent::SnippetEdit {
 3497                                        buffer_id,
 3498                                        edits: snippet_edits,
 3499                                        most_recent_edit,
 3500                                    });
 3501                                }
 3502                            }
 3503
 3504                            local.edits_from_lsp(
 3505                                &buffer_to_edit,
 3506                                edits,
 3507                                language_server.server_id(),
 3508                                op.text_document.version,
 3509                                cx,
 3510                            )
 3511                        })
 3512                        .await?;
 3513
 3514                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3515                        buffer.finalize_last_transaction();
 3516                        buffer.start_transaction();
 3517                        for (range, text) in edits {
 3518                            buffer.edit([(range, text)], None, cx);
 3519                        }
 3520
 3521                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3522                            if push_to_history {
 3523                                buffer.finalize_last_transaction();
 3524                                buffer.get_transaction(transaction_id).cloned()
 3525                            } else {
 3526                                buffer.forget_transaction(transaction_id)
 3527                            }
 3528                        })
 3529                    });
 3530                    if let Some(transaction) = transaction {
 3531                        project_transaction.0.insert(buffer_to_edit, transaction);
 3532                    }
 3533                }
 3534            }
 3535        }
 3536
 3537        Ok(project_transaction)
 3538    }
 3539
 3540    async fn on_lsp_workspace_edit(
 3541        this: WeakEntity<LspStore>,
 3542        params: lsp::ApplyWorkspaceEditParams,
 3543        server_id: LanguageServerId,
 3544        cx: &mut AsyncApp,
 3545    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3546        let this = this.upgrade().context("project project closed")?;
 3547        let language_server = this
 3548            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3549            .context("language server not found")?;
 3550        let transaction = Self::deserialize_workspace_edit(
 3551            this.clone(),
 3552            params.edit,
 3553            true,
 3554            language_server.clone(),
 3555            cx,
 3556        )
 3557        .await
 3558        .log_err();
 3559        this.update(cx, |this, cx| {
 3560            if let Some(transaction) = transaction {
 3561                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3562
 3563                this.as_local_mut()
 3564                    .unwrap()
 3565                    .last_workspace_edits_by_language_server
 3566                    .insert(server_id, transaction);
 3567            }
 3568        });
 3569        Ok(lsp::ApplyWorkspaceEditResponse {
 3570            applied: true,
 3571            failed_change: None,
 3572            failure_reason: None,
 3573        })
 3574    }
 3575
 3576    fn remove_worktree(
 3577        &mut self,
 3578        id_to_remove: WorktreeId,
 3579        cx: &mut Context<LspStore>,
 3580    ) -> Vec<LanguageServerId> {
 3581        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3582        self.diagnostics.remove(&id_to_remove);
 3583        self.prettier_store.update(cx, |prettier_store, cx| {
 3584            prettier_store.remove_worktree(id_to_remove, cx);
 3585        });
 3586
 3587        let mut servers_to_remove = BTreeSet::default();
 3588        let mut servers_to_preserve = HashSet::default();
 3589        for (seed, state) in &self.language_server_ids {
 3590            if seed.worktree_id == id_to_remove {
 3591                servers_to_remove.insert(state.id);
 3592            } else {
 3593                servers_to_preserve.insert(state.id);
 3594            }
 3595        }
 3596        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3597        self.language_server_ids
 3598            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3599        for server_id_to_remove in &servers_to_remove {
 3600            self.language_server_watched_paths
 3601                .remove(server_id_to_remove);
 3602            self.language_server_paths_watched_for_rename
 3603                .remove(server_id_to_remove);
 3604            self.last_workspace_edits_by_language_server
 3605                .remove(server_id_to_remove);
 3606            self.language_servers.remove(server_id_to_remove);
 3607            self.buffer_pull_diagnostics_result_ids
 3608                .remove(server_id_to_remove);
 3609            self.workspace_pull_diagnostics_result_ids
 3610                .remove(server_id_to_remove);
 3611            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3612                buffer_servers.remove(server_id_to_remove);
 3613            }
 3614            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3615        }
 3616        servers_to_remove.into_iter().collect()
 3617    }
 3618
 3619    fn rebuild_watched_paths_inner<'a>(
 3620        &'a self,
 3621        language_server_id: LanguageServerId,
 3622        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3623        cx: &mut Context<LspStore>,
 3624    ) -> LanguageServerWatchedPathsBuilder {
 3625        let worktrees = self
 3626            .worktree_store
 3627            .read(cx)
 3628            .worktrees()
 3629            .filter_map(|worktree| {
 3630                self.language_servers_for_worktree(worktree.read(cx).id())
 3631                    .find(|server| server.server_id() == language_server_id)
 3632                    .map(|_| worktree)
 3633            })
 3634            .collect::<Vec<_>>();
 3635
 3636        let mut worktree_globs = HashMap::default();
 3637        let mut abs_globs = HashMap::default();
 3638        log::trace!(
 3639            "Processing new watcher paths for language server with id {}",
 3640            language_server_id
 3641        );
 3642
 3643        for watcher in watchers {
 3644            if let Some((worktree, literal_prefix, pattern)) =
 3645                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3646            {
 3647                worktree.update(cx, |worktree, _| {
 3648                    if let Some((tree, glob)) =
 3649                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3650                    {
 3651                        tree.add_path_prefix_to_scan(literal_prefix);
 3652                        worktree_globs
 3653                            .entry(tree.id())
 3654                            .or_insert_with(GlobSetBuilder::new)
 3655                            .add(glob);
 3656                    }
 3657                });
 3658            } else {
 3659                let (path, pattern) = match &watcher.glob_pattern {
 3660                    lsp::GlobPattern::String(s) => {
 3661                        let watcher_path = SanitizedPath::new(s);
 3662                        let path = glob_literal_prefix(watcher_path.as_path());
 3663                        let pattern = watcher_path
 3664                            .as_path()
 3665                            .strip_prefix(&path)
 3666                            .map(|p| p.to_string_lossy().into_owned())
 3667                            .unwrap_or_else(|e| {
 3668                                debug_panic!(
 3669                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3670                                    s,
 3671                                    path.display(),
 3672                                    e
 3673                                );
 3674                                watcher_path.as_path().to_string_lossy().into_owned()
 3675                            });
 3676                        (path, pattern)
 3677                    }
 3678                    lsp::GlobPattern::Relative(rp) => {
 3679                        let Ok(mut base_uri) = match &rp.base_uri {
 3680                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3681                            lsp::OneOf::Right(base_uri) => base_uri,
 3682                        }
 3683                        .to_file_path() else {
 3684                            continue;
 3685                        };
 3686
 3687                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3688                        let pattern = Path::new(&rp.pattern)
 3689                            .strip_prefix(&path)
 3690                            .map(|p| p.to_string_lossy().into_owned())
 3691                            .unwrap_or_else(|e| {
 3692                                debug_panic!(
 3693                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3694                                    rp.pattern,
 3695                                    path.display(),
 3696                                    e
 3697                                );
 3698                                rp.pattern.clone()
 3699                            });
 3700                        base_uri.push(path);
 3701                        (base_uri, pattern)
 3702                    }
 3703                };
 3704
 3705                if let Some(glob) = Glob::new(&pattern).log_err() {
 3706                    if !path
 3707                        .components()
 3708                        .any(|c| matches!(c, path::Component::Normal(_)))
 3709                    {
 3710                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3711                        // rather than adding a new watcher for `/`.
 3712                        for worktree in &worktrees {
 3713                            worktree_globs
 3714                                .entry(worktree.read(cx).id())
 3715                                .or_insert_with(GlobSetBuilder::new)
 3716                                .add(glob.clone());
 3717                        }
 3718                    } else {
 3719                        abs_globs
 3720                            .entry(path.into())
 3721                            .or_insert_with(GlobSetBuilder::new)
 3722                            .add(glob);
 3723                    }
 3724                }
 3725            }
 3726        }
 3727
 3728        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3729        for (worktree_id, builder) in worktree_globs {
 3730            if let Ok(globset) = builder.build() {
 3731                watch_builder.watch_worktree(worktree_id, globset);
 3732            }
 3733        }
 3734        for (abs_path, builder) in abs_globs {
 3735            if let Ok(globset) = builder.build() {
 3736                watch_builder.watch_abs_path(abs_path, globset);
 3737            }
 3738        }
 3739        watch_builder
 3740    }
 3741
 3742    fn worktree_and_path_for_file_watcher(
 3743        worktrees: &[Entity<Worktree>],
 3744        watcher: &FileSystemWatcher,
 3745        cx: &App,
 3746    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3747        worktrees.iter().find_map(|worktree| {
 3748            let tree = worktree.read(cx);
 3749            let worktree_root_path = tree.abs_path();
 3750            let path_style = tree.path_style();
 3751            match &watcher.glob_pattern {
 3752                lsp::GlobPattern::String(s) => {
 3753                    let watcher_path = SanitizedPath::new(s);
 3754                    let relative = watcher_path
 3755                        .as_path()
 3756                        .strip_prefix(&worktree_root_path)
 3757                        .ok()?;
 3758                    let literal_prefix = glob_literal_prefix(relative);
 3759                    Some((
 3760                        worktree.clone(),
 3761                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3762                        relative.to_string_lossy().into_owned(),
 3763                    ))
 3764                }
 3765                lsp::GlobPattern::Relative(rp) => {
 3766                    let base_uri = match &rp.base_uri {
 3767                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3768                        lsp::OneOf::Right(base_uri) => base_uri,
 3769                    }
 3770                    .to_file_path()
 3771                    .ok()?;
 3772                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3773                    let mut literal_prefix = relative.to_owned();
 3774                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3775                    Some((
 3776                        worktree.clone(),
 3777                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3778                        rp.pattern.clone(),
 3779                    ))
 3780                }
 3781            }
 3782        })
 3783    }
 3784
 3785    fn rebuild_watched_paths(
 3786        &mut self,
 3787        language_server_id: LanguageServerId,
 3788        cx: &mut Context<LspStore>,
 3789    ) {
 3790        let Some(registrations) = self
 3791            .language_server_dynamic_registrations
 3792            .get(&language_server_id)
 3793        else {
 3794            return;
 3795        };
 3796
 3797        let watch_builder = self.rebuild_watched_paths_inner(
 3798            language_server_id,
 3799            registrations.did_change_watched_files.values().flatten(),
 3800            cx,
 3801        );
 3802        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3803        self.language_server_watched_paths
 3804            .insert(language_server_id, watcher);
 3805
 3806        cx.notify();
 3807    }
 3808
 3809    fn on_lsp_did_change_watched_files(
 3810        &mut self,
 3811        language_server_id: LanguageServerId,
 3812        registration_id: &str,
 3813        params: DidChangeWatchedFilesRegistrationOptions,
 3814        cx: &mut Context<LspStore>,
 3815    ) {
 3816        let registrations = self
 3817            .language_server_dynamic_registrations
 3818            .entry(language_server_id)
 3819            .or_default();
 3820
 3821        registrations
 3822            .did_change_watched_files
 3823            .insert(registration_id.to_string(), params.watchers);
 3824
 3825        self.rebuild_watched_paths(language_server_id, cx);
 3826    }
 3827
 3828    fn on_lsp_unregister_did_change_watched_files(
 3829        &mut self,
 3830        language_server_id: LanguageServerId,
 3831        registration_id: &str,
 3832        cx: &mut Context<LspStore>,
 3833    ) {
 3834        let registrations = self
 3835            .language_server_dynamic_registrations
 3836            .entry(language_server_id)
 3837            .or_default();
 3838
 3839        if registrations
 3840            .did_change_watched_files
 3841            .remove(registration_id)
 3842            .is_some()
 3843        {
 3844            log::info!(
 3845                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3846                language_server_id,
 3847                registration_id
 3848            );
 3849        } else {
 3850            log::warn!(
 3851                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3852                language_server_id,
 3853                registration_id
 3854            );
 3855        }
 3856
 3857        self.rebuild_watched_paths(language_server_id, cx);
 3858    }
 3859
 3860    async fn initialization_options_for_adapter(
 3861        adapter: Arc<dyn LspAdapter>,
 3862        delegate: &Arc<dyn LspAdapterDelegate>,
 3863        cx: &mut AsyncApp,
 3864    ) -> Result<Option<serde_json::Value>> {
 3865        let Some(mut initialization_config) =
 3866            adapter.clone().initialization_options(delegate, cx).await?
 3867        else {
 3868            return Ok(None);
 3869        };
 3870
 3871        for other_adapter in delegate.registered_lsp_adapters() {
 3872            if other_adapter.name() == adapter.name() {
 3873                continue;
 3874            }
 3875            if let Ok(Some(target_config)) = other_adapter
 3876                .clone()
 3877                .additional_initialization_options(adapter.name(), delegate)
 3878                .await
 3879            {
 3880                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3881            }
 3882        }
 3883
 3884        Ok(Some(initialization_config))
 3885    }
 3886
 3887    async fn workspace_configuration_for_adapter(
 3888        adapter: Arc<dyn LspAdapter>,
 3889        delegate: &Arc<dyn LspAdapterDelegate>,
 3890        toolchain: Option<Toolchain>,
 3891        requested_uri: Option<Uri>,
 3892        cx: &mut AsyncApp,
 3893    ) -> Result<serde_json::Value> {
 3894        let mut workspace_config = adapter
 3895            .clone()
 3896            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3897            .await?;
 3898
 3899        for other_adapter in delegate.registered_lsp_adapters() {
 3900            if other_adapter.name() == adapter.name() {
 3901                continue;
 3902            }
 3903            if let Ok(Some(target_config)) = other_adapter
 3904                .clone()
 3905                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3906                .await
 3907            {
 3908                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3909            }
 3910        }
 3911
 3912        Ok(workspace_config)
 3913    }
 3914
 3915    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3916        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3917            Some(server.clone())
 3918        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3919            Some(Arc::clone(server))
 3920        } else {
 3921            None
 3922        }
 3923    }
 3924}
 3925
 3926fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3927    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3928        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3929            language_server_id: server.server_id(),
 3930            name: Some(server.name()),
 3931            message: proto::update_language_server::Variant::MetadataUpdated(
 3932                proto::ServerMetadataUpdated {
 3933                    capabilities: Some(capabilities),
 3934                    binary: Some(proto::LanguageServerBinaryInfo {
 3935                        path: server.binary().path.to_string_lossy().into_owned(),
 3936                        arguments: server
 3937                            .binary()
 3938                            .arguments
 3939                            .iter()
 3940                            .map(|arg| arg.to_string_lossy().into_owned())
 3941                            .collect(),
 3942                    }),
 3943                    configuration: serde_json::to_string(server.configuration()).ok(),
 3944                    workspace_folders: server
 3945                        .workspace_folders()
 3946                        .iter()
 3947                        .map(|uri| uri.to_string())
 3948                        .collect(),
 3949                },
 3950            ),
 3951        });
 3952    }
 3953}
 3954
 3955#[derive(Debug)]
 3956pub struct FormattableBuffer {
 3957    handle: Entity<Buffer>,
 3958    abs_path: Option<PathBuf>,
 3959    env: Option<HashMap<String, String>>,
 3960    ranges: Option<Vec<Range<Anchor>>>,
 3961}
 3962
 3963pub struct RemoteLspStore {
 3964    upstream_client: Option<AnyProtoClient>,
 3965    upstream_project_id: u64,
 3966}
 3967
 3968pub(crate) enum LspStoreMode {
 3969    Local(LocalLspStore),   // ssh host and collab host
 3970    Remote(RemoteLspStore), // collab guest
 3971}
 3972
 3973impl LspStoreMode {
 3974    fn is_local(&self) -> bool {
 3975        matches!(self, LspStoreMode::Local(_))
 3976    }
 3977}
 3978
 3979pub struct LspStore {
 3980    mode: LspStoreMode,
 3981    last_formatting_failure: Option<String>,
 3982    downstream_client: Option<(AnyProtoClient, u64)>,
 3983    nonce: u128,
 3984    buffer_store: Entity<BufferStore>,
 3985    worktree_store: Entity<WorktreeStore>,
 3986    pub languages: Arc<LanguageRegistry>,
 3987    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3988    active_entry: Option<ProjectEntryId>,
 3989    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3990    _maintain_buffer_languages: Task<()>,
 3991    diagnostic_summaries:
 3992        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3993    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3994    semantic_token_config: SemanticTokenConfig,
 3995    lsp_data: HashMap<BufferId, BufferLspData>,
 3996    buffer_reload_tasks: HashMap<BufferId, Task<anyhow::Result<()>>>,
 3997    next_hint_id: Arc<AtomicUsize>,
 3998}
 3999
 4000#[derive(Debug)]
 4001pub struct BufferLspData {
 4002    buffer_version: Global,
 4003    document_colors: Option<DocumentColorData>,
 4004    code_lens: Option<CodeLensData>,
 4005    semantic_tokens: Option<SemanticTokensData>,
 4006    folding_ranges: Option<FoldingRangeData>,
 4007    document_symbols: Option<DocumentSymbolsData>,
 4008    inlay_hints: BufferInlayHints,
 4009    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 4010    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 4011}
 4012
 4013#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 4014struct LspKey {
 4015    request_type: TypeId,
 4016    server_queried: Option<LanguageServerId>,
 4017}
 4018
 4019impl BufferLspData {
 4020    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 4021        Self {
 4022            buffer_version: buffer.read(cx).version(),
 4023            document_colors: None,
 4024            code_lens: None,
 4025            semantic_tokens: None,
 4026            folding_ranges: None,
 4027            document_symbols: None,
 4028            inlay_hints: BufferInlayHints::new(buffer, cx),
 4029            lsp_requests: HashMap::default(),
 4030            chunk_lsp_requests: HashMap::default(),
 4031        }
 4032    }
 4033
 4034    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 4035        if let Some(document_colors) = &mut self.document_colors {
 4036            document_colors.remove_server_data(for_server);
 4037        }
 4038
 4039        if let Some(code_lens) = &mut self.code_lens {
 4040            code_lens.remove_server_data(for_server);
 4041        }
 4042
 4043        self.inlay_hints.remove_server_data(for_server);
 4044
 4045        if let Some(semantic_tokens) = &mut self.semantic_tokens {
 4046            semantic_tokens.remove_server_data(for_server);
 4047        }
 4048
 4049        if let Some(folding_ranges) = &mut self.folding_ranges {
 4050            folding_ranges.ranges.remove(&for_server);
 4051        }
 4052
 4053        if let Some(document_symbols) = &mut self.document_symbols {
 4054            document_symbols.remove_server_data(for_server);
 4055        }
 4056    }
 4057
 4058    #[cfg(any(test, feature = "test-support"))]
 4059    pub fn inlay_hints(&self) -> &BufferInlayHints {
 4060        &self.inlay_hints
 4061    }
 4062}
 4063
 4064#[derive(Debug)]
 4065pub enum LspStoreEvent {
 4066    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 4067    LanguageServerRemoved(LanguageServerId),
 4068    LanguageServerUpdate {
 4069        language_server_id: LanguageServerId,
 4070        name: Option<LanguageServerName>,
 4071        message: proto::update_language_server::Variant,
 4072    },
 4073    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 4074    LanguageServerPrompt(LanguageServerPromptRequest),
 4075    LanguageDetected {
 4076        buffer: Entity<Buffer>,
 4077        new_language: Option<Arc<Language>>,
 4078    },
 4079    Notification(String),
 4080    RefreshInlayHints {
 4081        server_id: LanguageServerId,
 4082        request_id: Option<usize>,
 4083    },
 4084    RefreshSemanticTokens {
 4085        server_id: LanguageServerId,
 4086        request_id: Option<usize>,
 4087    },
 4088    RefreshCodeLens,
 4089    DiagnosticsUpdated {
 4090        server_id: LanguageServerId,
 4091        paths: Vec<ProjectPath>,
 4092    },
 4093    DiskBasedDiagnosticsStarted {
 4094        language_server_id: LanguageServerId,
 4095    },
 4096    DiskBasedDiagnosticsFinished {
 4097        language_server_id: LanguageServerId,
 4098    },
 4099    SnippetEdit {
 4100        buffer_id: BufferId,
 4101        edits: Vec<(lsp::Range, Snippet)>,
 4102        most_recent_edit: clock::Lamport,
 4103    },
 4104    WorkspaceEditApplied(ProjectTransaction),
 4105}
 4106
 4107#[derive(Clone, Debug, Serialize)]
 4108pub struct LanguageServerStatus {
 4109    pub name: LanguageServerName,
 4110    pub server_version: Option<SharedString>,
 4111    pub server_readable_version: Option<SharedString>,
 4112    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 4113    pub has_pending_diagnostic_updates: bool,
 4114    pub progress_tokens: HashSet<ProgressToken>,
 4115    pub worktree: Option<WorktreeId>,
 4116    pub binary: Option<LanguageServerBinary>,
 4117    pub configuration: Option<Value>,
 4118    pub workspace_folders: BTreeSet<Uri>,
 4119    pub process_id: Option<u32>,
 4120}
 4121
 4122#[derive(Clone, Debug)]
 4123struct CoreSymbol {
 4124    pub language_server_name: LanguageServerName,
 4125    pub source_worktree_id: WorktreeId,
 4126    pub source_language_server_id: LanguageServerId,
 4127    pub path: SymbolLocation,
 4128    pub name: String,
 4129    pub kind: lsp::SymbolKind,
 4130    pub range: Range<Unclipped<PointUtf16>>,
 4131    pub container_name: Option<String>,
 4132}
 4133
 4134#[derive(Clone, Debug, PartialEq, Eq)]
 4135pub enum SymbolLocation {
 4136    InProject(ProjectPath),
 4137    OutsideProject {
 4138        abs_path: Arc<Path>,
 4139        signature: [u8; 32],
 4140    },
 4141}
 4142
 4143impl SymbolLocation {
 4144    fn file_name(&self) -> Option<&str> {
 4145        match self {
 4146            Self::InProject(path) => path.path.file_name(),
 4147            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 4148        }
 4149    }
 4150}
 4151
 4152impl LspStore {
 4153    pub fn init(client: &AnyProtoClient) {
 4154        client.add_entity_request_handler(Self::handle_lsp_query);
 4155        client.add_entity_message_handler(Self::handle_lsp_query_response);
 4156        client.add_entity_request_handler(Self::handle_restart_language_servers);
 4157        client.add_entity_request_handler(Self::handle_stop_language_servers);
 4158        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 4159        client.add_entity_message_handler(Self::handle_start_language_server);
 4160        client.add_entity_message_handler(Self::handle_update_language_server);
 4161        client.add_entity_message_handler(Self::handle_language_server_log);
 4162        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 4163        client.add_entity_request_handler(Self::handle_format_buffers);
 4164        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 4165        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 4166        client.add_entity_request_handler(Self::handle_apply_code_action);
 4167        client.add_entity_request_handler(Self::handle_get_project_symbols);
 4168        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 4169        client.add_entity_request_handler(Self::handle_get_color_presentation);
 4170        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 4171        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 4172        client.add_entity_request_handler(Self::handle_refresh_semantic_tokens);
 4173        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 4174        client.add_entity_request_handler(Self::handle_on_type_formatting);
 4175        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 4176        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 4177        client.add_entity_request_handler(Self::handle_rename_project_entry);
 4178        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 4179        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 4180        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 4181        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 4182        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 4183        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 4184        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 4185
 4186        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 4187        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 4188        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 4189        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 4190        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 4191        client.add_entity_request_handler(
 4192            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 4193        );
 4194        client.add_entity_request_handler(
 4195            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 4196        );
 4197        client.add_entity_request_handler(
 4198            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 4199        );
 4200    }
 4201
 4202    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 4203        match &self.mode {
 4204            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 4205            _ => None,
 4206        }
 4207    }
 4208
 4209    pub fn as_local(&self) -> Option<&LocalLspStore> {
 4210        match &self.mode {
 4211            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4212            _ => None,
 4213        }
 4214    }
 4215
 4216    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 4217        match &mut self.mode {
 4218            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 4219            _ => None,
 4220        }
 4221    }
 4222
 4223    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4224        match &self.mode {
 4225            LspStoreMode::Remote(RemoteLspStore {
 4226                upstream_client: Some(upstream_client),
 4227                upstream_project_id,
 4228                ..
 4229            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4230
 4231            LspStoreMode::Remote(RemoteLspStore {
 4232                upstream_client: None,
 4233                ..
 4234            }) => None,
 4235            LspStoreMode::Local(_) => None,
 4236        }
 4237    }
 4238
 4239    pub fn new_local(
 4240        buffer_store: Entity<BufferStore>,
 4241        worktree_store: Entity<WorktreeStore>,
 4242        prettier_store: Entity<PrettierStore>,
 4243        toolchain_store: Entity<LocalToolchainStore>,
 4244        environment: Entity<ProjectEnvironment>,
 4245        manifest_tree: Entity<ManifestTree>,
 4246        languages: Arc<LanguageRegistry>,
 4247        http_client: Arc<dyn HttpClient>,
 4248        fs: Arc<dyn Fs>,
 4249        cx: &mut Context<Self>,
 4250    ) -> Self {
 4251        let yarn = YarnPathStore::new(fs.clone(), cx);
 4252        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4253            .detach();
 4254        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4255            .detach();
 4256        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4257            .detach();
 4258        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4259            .detach();
 4260        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4261            .detach();
 4262        subscribe_to_binary_statuses(&languages, cx).detach();
 4263
 4264        let _maintain_workspace_config = {
 4265            let (sender, receiver) = watch::channel();
 4266            (Self::maintain_workspace_config(receiver, cx), sender)
 4267        };
 4268
 4269        Self {
 4270            mode: LspStoreMode::Local(LocalLspStore {
 4271                weak: cx.weak_entity(),
 4272                worktree_store: worktree_store.clone(),
 4273
 4274                supplementary_language_servers: Default::default(),
 4275                languages: languages.clone(),
 4276                language_server_ids: Default::default(),
 4277                language_servers: Default::default(),
 4278                last_workspace_edits_by_language_server: Default::default(),
 4279                language_server_watched_paths: Default::default(),
 4280                language_server_paths_watched_for_rename: Default::default(),
 4281                language_server_dynamic_registrations: Default::default(),
 4282                buffers_being_formatted: Default::default(),
 4283                buffers_to_refresh_hash_set: HashSet::default(),
 4284                buffers_to_refresh_queue: VecDeque::new(),
 4285                _background_diagnostics_worker: Task::ready(()).shared(),
 4286                buffer_snapshots: Default::default(),
 4287                prettier_store,
 4288                environment,
 4289                http_client,
 4290                fs,
 4291                yarn,
 4292                next_diagnostic_group_id: Default::default(),
 4293                diagnostics: Default::default(),
 4294                _subscription: cx.on_app_quit(|this, _| {
 4295                    this.as_local_mut()
 4296                        .unwrap()
 4297                        .shutdown_language_servers_on_quit()
 4298                }),
 4299                lsp_tree: LanguageServerTree::new(
 4300                    manifest_tree,
 4301                    languages.clone(),
 4302                    toolchain_store.clone(),
 4303                ),
 4304                toolchain_store,
 4305                registered_buffers: HashMap::default(),
 4306                buffers_opened_in_servers: HashMap::default(),
 4307                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4308                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4309                restricted_worktrees_tasks: HashMap::default(),
 4310                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4311                    .manifest_file_names(),
 4312            }),
 4313            last_formatting_failure: None,
 4314            downstream_client: None,
 4315            buffer_store,
 4316            worktree_store,
 4317            languages: languages.clone(),
 4318            language_server_statuses: Default::default(),
 4319            nonce: StdRng::from_os_rng().random(),
 4320            diagnostic_summaries: HashMap::default(),
 4321            lsp_server_capabilities: HashMap::default(),
 4322            semantic_token_config: SemanticTokenConfig::new(cx),
 4323            lsp_data: HashMap::default(),
 4324            buffer_reload_tasks: HashMap::default(),
 4325            next_hint_id: Arc::default(),
 4326            active_entry: None,
 4327            _maintain_workspace_config,
 4328            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4329        }
 4330    }
 4331
 4332    fn send_lsp_proto_request<R: LspCommand>(
 4333        &self,
 4334        buffer: Entity<Buffer>,
 4335        client: AnyProtoClient,
 4336        upstream_project_id: u64,
 4337        request: R,
 4338        cx: &mut Context<LspStore>,
 4339    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4340        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4341            return Task::ready(Ok(R::Response::default()));
 4342        }
 4343        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4344        cx.spawn(async move |this, cx| {
 4345            let response = client.request(message).await?;
 4346            let this = this.upgrade().context("project dropped")?;
 4347            request
 4348                .response_from_proto(response, this, buffer, cx.clone())
 4349                .await
 4350        })
 4351    }
 4352
 4353    pub(super) fn new_remote(
 4354        buffer_store: Entity<BufferStore>,
 4355        worktree_store: Entity<WorktreeStore>,
 4356        languages: Arc<LanguageRegistry>,
 4357        upstream_client: AnyProtoClient,
 4358        project_id: u64,
 4359        cx: &mut Context<Self>,
 4360    ) -> Self {
 4361        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4362            .detach();
 4363        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4364            .detach();
 4365        subscribe_to_binary_statuses(&languages, cx).detach();
 4366        let _maintain_workspace_config = {
 4367            let (sender, receiver) = watch::channel();
 4368            (Self::maintain_workspace_config(receiver, cx), sender)
 4369        };
 4370        Self {
 4371            mode: LspStoreMode::Remote(RemoteLspStore {
 4372                upstream_client: Some(upstream_client),
 4373                upstream_project_id: project_id,
 4374            }),
 4375            downstream_client: None,
 4376            last_formatting_failure: None,
 4377            buffer_store,
 4378            worktree_store,
 4379            languages: languages.clone(),
 4380            language_server_statuses: Default::default(),
 4381            nonce: StdRng::from_os_rng().random(),
 4382            diagnostic_summaries: HashMap::default(),
 4383            lsp_server_capabilities: HashMap::default(),
 4384            semantic_token_config: SemanticTokenConfig::new(cx),
 4385            next_hint_id: Arc::default(),
 4386            lsp_data: HashMap::default(),
 4387            buffer_reload_tasks: HashMap::default(),
 4388            active_entry: None,
 4389
 4390            _maintain_workspace_config,
 4391            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4392        }
 4393    }
 4394
 4395    fn on_buffer_store_event(
 4396        &mut self,
 4397        _: Entity<BufferStore>,
 4398        event: &BufferStoreEvent,
 4399        cx: &mut Context<Self>,
 4400    ) {
 4401        match event {
 4402            BufferStoreEvent::BufferAdded(buffer) => {
 4403                self.on_buffer_added(buffer, cx).log_err();
 4404            }
 4405            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4406                let buffer_id = buffer.read(cx).remote_id();
 4407                if let Some(local) = self.as_local_mut()
 4408                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4409                {
 4410                    local.reset_buffer(buffer, old_file, cx);
 4411
 4412                    if local.registered_buffers.contains_key(&buffer_id) {
 4413                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4414                    }
 4415                }
 4416
 4417                self.detect_language_for_buffer(buffer, cx);
 4418                if let Some(local) = self.as_local_mut() {
 4419                    local.initialize_buffer(buffer, cx);
 4420                    if local.registered_buffers.contains_key(&buffer_id) {
 4421                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4422                    }
 4423                }
 4424            }
 4425            _ => {}
 4426        }
 4427    }
 4428
 4429    fn on_worktree_store_event(
 4430        &mut self,
 4431        _: Entity<WorktreeStore>,
 4432        event: &WorktreeStoreEvent,
 4433        cx: &mut Context<Self>,
 4434    ) {
 4435        match event {
 4436            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4437                if !worktree.read(cx).is_local() {
 4438                    return;
 4439                }
 4440                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4441                    worktree::Event::UpdatedEntries(changes) => {
 4442                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4443                    }
 4444                    worktree::Event::UpdatedGitRepositories(_)
 4445                    | worktree::Event::DeletedEntry(_)
 4446                    | worktree::Event::Deleted
 4447                    | worktree::Event::UpdatedRootRepoCommonDir { .. } => {}
 4448                })
 4449                .detach()
 4450            }
 4451            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4452            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4453                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4454            }
 4455            WorktreeStoreEvent::WorktreeUpdatedEntries(worktree_id, changes) => {
 4456                self.invalidate_diagnostic_summaries_for_removed_entries(*worktree_id, changes, cx);
 4457            }
 4458            WorktreeStoreEvent::WorktreeReleased(..)
 4459            | WorktreeStoreEvent::WorktreeOrderChanged
 4460            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4461            | WorktreeStoreEvent::WorktreeDeletedEntry(..)
 4462            | WorktreeStoreEvent::WorktreeUpdatedRootRepoCommonDir(..) => {}
 4463        }
 4464    }
 4465
 4466    fn on_prettier_store_event(
 4467        &mut self,
 4468        _: Entity<PrettierStore>,
 4469        event: &PrettierStoreEvent,
 4470        cx: &mut Context<Self>,
 4471    ) {
 4472        match event {
 4473            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4474                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4475            }
 4476            PrettierStoreEvent::LanguageServerAdded {
 4477                new_server_id,
 4478                name,
 4479                prettier_server,
 4480            } => {
 4481                self.register_supplementary_language_server(
 4482                    *new_server_id,
 4483                    name.clone(),
 4484                    prettier_server.clone(),
 4485                    cx,
 4486                );
 4487            }
 4488        }
 4489    }
 4490
 4491    fn on_toolchain_store_event(
 4492        &mut self,
 4493        _: Entity<LocalToolchainStore>,
 4494        event: &ToolchainStoreEvent,
 4495        _: &mut Context<Self>,
 4496    ) {
 4497        if let ToolchainStoreEvent::ToolchainActivated = event {
 4498            self.request_workspace_config_refresh()
 4499        }
 4500    }
 4501
 4502    fn request_workspace_config_refresh(&mut self) {
 4503        *self._maintain_workspace_config.1.borrow_mut() = ();
 4504    }
 4505
 4506    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4507        self.as_local().map(|local| local.prettier_store.clone())
 4508    }
 4509
 4510    fn on_buffer_event(
 4511        &mut self,
 4512        buffer: Entity<Buffer>,
 4513        event: &language::BufferEvent,
 4514        cx: &mut Context<Self>,
 4515    ) {
 4516        match event {
 4517            language::BufferEvent::Edited { .. } => {
 4518                self.on_buffer_edited(buffer, cx);
 4519            }
 4520
 4521            language::BufferEvent::Saved => {
 4522                self.on_buffer_saved(buffer, cx);
 4523            }
 4524
 4525            language::BufferEvent::Reloaded => {
 4526                self.on_buffer_reloaded(buffer, cx);
 4527            }
 4528
 4529            _ => {}
 4530        }
 4531    }
 4532
 4533    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4534        buffer
 4535            .read(cx)
 4536            .set_language_registry(self.languages.clone());
 4537
 4538        cx.subscribe(buffer, |this, buffer, event, cx| {
 4539            this.on_buffer_event(buffer, event, cx);
 4540        })
 4541        .detach();
 4542
 4543        self.parse_modeline(buffer, cx);
 4544        self.detect_language_for_buffer(buffer, cx);
 4545        if let Some(local) = self.as_local_mut() {
 4546            local.initialize_buffer(buffer, cx);
 4547        }
 4548
 4549        Ok(())
 4550    }
 4551
 4552    pub fn refresh_background_diagnostics_for_buffers(
 4553        &mut self,
 4554        buffers: HashSet<BufferId>,
 4555        cx: &mut Context<Self>,
 4556    ) -> Shared<Task<()>> {
 4557        let Some(local) = self.as_local_mut() else {
 4558            return Task::ready(()).shared();
 4559        };
 4560        for buffer in buffers {
 4561            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4562                local.buffers_to_refresh_queue.push_back(buffer);
 4563                if local.buffers_to_refresh_queue.len() == 1 {
 4564                    local._background_diagnostics_worker =
 4565                        Self::background_diagnostics_worker(cx).shared();
 4566                }
 4567            }
 4568        }
 4569
 4570        local._background_diagnostics_worker.clone()
 4571    }
 4572
 4573    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4574        let buffer_store = self.buffer_store.clone();
 4575        let local = self.as_local_mut()?;
 4576        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4577            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4578            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4579                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4580            }
 4581        }
 4582        None
 4583    }
 4584
 4585    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4586        cx.spawn(async move |this, cx| {
 4587            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4588                task.await.log_err();
 4589            }
 4590        })
 4591    }
 4592
 4593    fn on_buffer_reloaded(&mut self, buffer: Entity<Buffer>, cx: &mut Context<Self>) {
 4594        if self.parse_modeline(&buffer, cx) {
 4595            self.detect_language_for_buffer(&buffer, cx);
 4596        }
 4597
 4598        let buffer_id = buffer.read(cx).remote_id();
 4599        let task = self.pull_diagnostics_for_buffer(buffer, cx);
 4600        self.buffer_reload_tasks.insert(buffer_id, task);
 4601    }
 4602
 4603    pub(crate) fn register_buffer_with_language_servers(
 4604        &mut self,
 4605        buffer: &Entity<Buffer>,
 4606        only_register_servers: HashSet<LanguageServerSelector>,
 4607        ignore_refcounts: bool,
 4608        cx: &mut Context<Self>,
 4609    ) -> OpenLspBufferHandle {
 4610        let buffer_id = buffer.read(cx).remote_id();
 4611        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4612        if let Some(local) = self.as_local_mut() {
 4613            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4614            if !ignore_refcounts {
 4615                *refcount += 1;
 4616            }
 4617
 4618            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4619            // 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
 4620            // 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
 4621            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4622            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4623                return handle;
 4624            };
 4625            if !file.is_local() {
 4626                return handle;
 4627            }
 4628
 4629            if ignore_refcounts || *refcount == 1 {
 4630                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4631            }
 4632            if !ignore_refcounts {
 4633                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4634                    let refcount = {
 4635                        let local = lsp_store.as_local_mut().unwrap();
 4636                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4637                            debug_panic!("bad refcounting");
 4638                            return;
 4639                        };
 4640
 4641                        *refcount -= 1;
 4642                        *refcount
 4643                    };
 4644                    if refcount == 0 {
 4645                        lsp_store.lsp_data.remove(&buffer_id);
 4646                        lsp_store.buffer_reload_tasks.remove(&buffer_id);
 4647                        let local = lsp_store.as_local_mut().unwrap();
 4648                        local.registered_buffers.remove(&buffer_id);
 4649
 4650                        local.buffers_opened_in_servers.remove(&buffer_id);
 4651                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4652                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4653
 4654                            let buffer_abs_path = file.abs_path(cx);
 4655                            for (_, buffer_pull_diagnostics_result_ids) in
 4656                                &mut local.buffer_pull_diagnostics_result_ids
 4657                            {
 4658                                buffer_pull_diagnostics_result_ids.retain(
 4659                                    |_, buffer_result_ids| {
 4660                                        buffer_result_ids.remove(&buffer_abs_path);
 4661                                        !buffer_result_ids.is_empty()
 4662                                    },
 4663                                );
 4664                            }
 4665
 4666                            let diagnostic_updates = local
 4667                                .language_servers
 4668                                .keys()
 4669                                .cloned()
 4670                                .map(|server_id| DocumentDiagnosticsUpdate {
 4671                                    diagnostics: DocumentDiagnostics {
 4672                                        document_abs_path: buffer_abs_path.clone(),
 4673                                        version: None,
 4674                                        diagnostics: Vec::new(),
 4675                                    },
 4676                                    result_id: None,
 4677                                    registration_id: None,
 4678                                    server_id,
 4679                                    disk_based_sources: Cow::Borrowed(&[]),
 4680                                })
 4681                                .collect::<Vec<_>>();
 4682
 4683                            lsp_store
 4684                                .merge_diagnostic_entries(
 4685                                    diagnostic_updates,
 4686                                    |_, diagnostic, _| {
 4687                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4688                                    },
 4689                                    cx,
 4690                                )
 4691                                .context("Clearing diagnostics for the closed buffer")
 4692                                .log_err();
 4693                        }
 4694                    }
 4695                })
 4696                .detach();
 4697            }
 4698        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4699            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4700            cx.background_spawn(async move {
 4701                upstream_client
 4702                    .request(proto::RegisterBufferWithLanguageServers {
 4703                        project_id: upstream_project_id,
 4704                        buffer_id,
 4705                        only_servers: only_register_servers
 4706                            .into_iter()
 4707                            .map(|selector| {
 4708                                let selector = match selector {
 4709                                    LanguageServerSelector::Id(language_server_id) => {
 4710                                        proto::language_server_selector::Selector::ServerId(
 4711                                            language_server_id.to_proto(),
 4712                                        )
 4713                                    }
 4714                                    LanguageServerSelector::Name(language_server_name) => {
 4715                                        proto::language_server_selector::Selector::Name(
 4716                                            language_server_name.to_string(),
 4717                                        )
 4718                                    }
 4719                                };
 4720                                proto::LanguageServerSelector {
 4721                                    selector: Some(selector),
 4722                                }
 4723                            })
 4724                            .collect(),
 4725                    })
 4726                    .await
 4727            })
 4728            .detach();
 4729        } else {
 4730            // Our remote connection got closed
 4731        }
 4732        handle
 4733    }
 4734
 4735    fn maintain_buffer_languages(
 4736        languages: Arc<LanguageRegistry>,
 4737        cx: &mut Context<Self>,
 4738    ) -> Task<()> {
 4739        let mut subscription = languages.subscribe();
 4740        let mut prev_reload_count = languages.reload_count();
 4741        cx.spawn(async move |this, cx| {
 4742            while let Some(()) = subscription.next().await {
 4743                if let Some(this) = this.upgrade() {
 4744                    // If the language registry has been reloaded, then remove and
 4745                    // re-assign the languages on all open buffers.
 4746                    let reload_count = languages.reload_count();
 4747                    if reload_count > prev_reload_count {
 4748                        prev_reload_count = reload_count;
 4749                        this.update(cx, |this, cx| {
 4750                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4751                                for buffer in buffer_store.buffers() {
 4752                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4753                                    {
 4754                                        buffer.update(cx, |buffer, cx| {
 4755                                            buffer.set_language_async(None, cx)
 4756                                        });
 4757                                        if let Some(local) = this.as_local_mut() {
 4758                                            local.reset_buffer(&buffer, &f, cx);
 4759
 4760                                            if local
 4761                                                .registered_buffers
 4762                                                .contains_key(&buffer.read(cx).remote_id())
 4763                                                && let Some(file_url) =
 4764                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4765                                            {
 4766                                                local.unregister_buffer_from_language_servers(
 4767                                                    &buffer, &file_url, cx,
 4768                                                );
 4769                                            }
 4770                                        }
 4771                                    }
 4772                                }
 4773                            });
 4774                        });
 4775                    }
 4776
 4777                    this.update(cx, |this, cx| {
 4778                        let mut plain_text_buffers = Vec::new();
 4779                        let mut buffers_with_language = Vec::new();
 4780                        let mut buffers_with_unknown_injections = Vec::new();
 4781                        for handle in this.buffer_store.read(cx).buffers() {
 4782                            let buffer = handle.read(cx);
 4783                            if buffer.language().is_none()
 4784                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4785                            {
 4786                                plain_text_buffers.push(handle);
 4787                            } else {
 4788                                if buffer.contains_unknown_injections() {
 4789                                    buffers_with_unknown_injections.push(handle.clone());
 4790                                }
 4791                                buffers_with_language.push(handle);
 4792                            }
 4793                        }
 4794
 4795                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4796                        // and reused later in the invisible worktrees.
 4797                        plain_text_buffers.sort_by_key(|buffer| {
 4798                            Reverse(
 4799                                File::from_dyn(buffer.read(cx).file())
 4800                                    .map(|file| file.worktree.read(cx).is_visible()),
 4801                            )
 4802                        });
 4803
 4804                        for buffer in plain_text_buffers {
 4805                            this.detect_language_for_buffer(&buffer, cx);
 4806                            if let Some(local) = this.as_local_mut() {
 4807                                local.initialize_buffer(&buffer, cx);
 4808                                if local
 4809                                    .registered_buffers
 4810                                    .contains_key(&buffer.read(cx).remote_id())
 4811                                {
 4812                                    local.register_buffer_with_language_servers(
 4813                                        &buffer,
 4814                                        HashSet::default(),
 4815                                        cx,
 4816                                    );
 4817                                }
 4818                            }
 4819                        }
 4820
 4821                        // Also register buffers that already have a language with
 4822                        // any newly-available language servers (e.g., from extensions
 4823                        // that finished loading after buffers were restored).
 4824                        if let Some(local) = this.as_local_mut() {
 4825                            for buffer in buffers_with_language {
 4826                                if local
 4827                                    .registered_buffers
 4828                                    .contains_key(&buffer.read(cx).remote_id())
 4829                                {
 4830                                    local.register_buffer_with_language_servers(
 4831                                        &buffer,
 4832                                        HashSet::default(),
 4833                                        cx,
 4834                                    );
 4835                                }
 4836                            }
 4837                        }
 4838
 4839                        for buffer in buffers_with_unknown_injections {
 4840                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4841                        }
 4842                    });
 4843                }
 4844            }
 4845        })
 4846    }
 4847
 4848    fn parse_modeline(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<Self>) -> bool {
 4849        let buffer = buffer_handle.read(cx);
 4850        let content = buffer.as_rope();
 4851
 4852        let modeline_settings = {
 4853            let settings_store = cx.global::<SettingsStore>();
 4854            let modeline_lines = settings_store
 4855                .raw_user_settings()
 4856                .and_then(|s| s.content.modeline_lines)
 4857                .or(settings_store.raw_default_settings().modeline_lines)
 4858                .unwrap_or(5);
 4859
 4860            const MAX_MODELINE_BYTES: usize = 1024;
 4861
 4862            let first_bytes =
 4863                content.clip_offset(content.len().min(MAX_MODELINE_BYTES), Bias::Left);
 4864            let mut first_lines = Vec::new();
 4865            let mut lines = content.chunks_in_range(0..first_bytes).lines();
 4866            for _ in 0..modeline_lines {
 4867                if let Some(line) = lines.next() {
 4868                    first_lines.push(line.to_string());
 4869                } else {
 4870                    break;
 4871                }
 4872            }
 4873            let first_lines_ref: Vec<_> = first_lines.iter().map(|line| line.as_str()).collect();
 4874
 4875            let last_start =
 4876                content.clip_offset(content.len().saturating_sub(MAX_MODELINE_BYTES), Bias::Left);
 4877            let mut last_lines = Vec::new();
 4878            let mut lines = content
 4879                .reversed_chunks_in_range(last_start..content.len())
 4880                .lines();
 4881            for _ in 0..modeline_lines {
 4882                if let Some(line) = lines.next() {
 4883                    last_lines.push(line.to_string());
 4884                } else {
 4885                    break;
 4886                }
 4887            }
 4888            let last_lines_ref: Vec<_> =
 4889                last_lines.iter().rev().map(|line| line.as_str()).collect();
 4890            modeline::parse_modeline(&first_lines_ref, &last_lines_ref)
 4891        };
 4892
 4893        log::debug!("Parsed modeline settings: {:?}", modeline_settings);
 4894
 4895        buffer_handle.update(cx, |buffer, _cx| buffer.set_modeline(modeline_settings))
 4896    }
 4897
 4898    fn detect_language_for_buffer(
 4899        &mut self,
 4900        buffer_handle: &Entity<Buffer>,
 4901        cx: &mut Context<Self>,
 4902    ) -> Option<language::AvailableLanguage> {
 4903        // If the buffer has a language, set it and start the language server if we haven't already.
 4904        let buffer = buffer_handle.read(cx);
 4905        let file = buffer.file()?;
 4906        let content = buffer.as_rope();
 4907        let modeline_settings = buffer.modeline().map(Arc::as_ref);
 4908
 4909        let available_language = if let Some(ModelineSettings {
 4910            mode: Some(mode_name),
 4911            ..
 4912        }) = modeline_settings
 4913        {
 4914            self.languages
 4915                .available_language_for_modeline_name(mode_name)
 4916        } else {
 4917            self.languages.language_for_file(file, Some(content), cx)
 4918        };
 4919        if let Some(available_language) = &available_language {
 4920            if let Some(Ok(Ok(new_language))) = self
 4921                .languages
 4922                .load_language(available_language)
 4923                .now_or_never()
 4924            {
 4925                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4926            }
 4927        } else {
 4928            cx.emit(LspStoreEvent::LanguageDetected {
 4929                buffer: buffer_handle.clone(),
 4930                new_language: None,
 4931            });
 4932        }
 4933
 4934        available_language
 4935    }
 4936
 4937    pub(crate) fn set_language_for_buffer(
 4938        &mut self,
 4939        buffer_entity: &Entity<Buffer>,
 4940        new_language: Arc<Language>,
 4941        cx: &mut Context<Self>,
 4942    ) {
 4943        let buffer = buffer_entity.read(cx);
 4944        let buffer_file = buffer.file().cloned();
 4945        let buffer_id = buffer.remote_id();
 4946        if let Some(local_store) = self.as_local_mut()
 4947            && local_store.registered_buffers.contains_key(&buffer_id)
 4948            && let Some(abs_path) =
 4949                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4950            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4951        {
 4952            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4953        }
 4954        buffer_entity.update(cx, |buffer, cx| {
 4955            if buffer
 4956                .language()
 4957                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4958            {
 4959                buffer.set_language_async(Some(new_language.clone()), cx);
 4960            }
 4961        });
 4962
 4963        let settings = LanguageSettings::resolve(
 4964            Some(&buffer_entity.read(cx)),
 4965            Some(&new_language.name()),
 4966            cx,
 4967        )
 4968        .into_owned();
 4969        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4970
 4971        let worktree_id = if let Some(file) = buffer_file {
 4972            let worktree = file.worktree.clone();
 4973
 4974            if let Some(local) = self.as_local_mut()
 4975                && local.registered_buffers.contains_key(&buffer_id)
 4976            {
 4977                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4978            }
 4979            Some(worktree.read(cx).id())
 4980        } else {
 4981            None
 4982        };
 4983
 4984        if settings.prettier.allowed
 4985            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4986        {
 4987            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4988            if let Some(prettier_store) = prettier_store {
 4989                prettier_store.update(cx, |prettier_store, cx| {
 4990                    prettier_store.install_default_prettier(
 4991                        worktree_id,
 4992                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4993                        cx,
 4994                    )
 4995                })
 4996            }
 4997        }
 4998
 4999        cx.emit(LspStoreEvent::LanguageDetected {
 5000            buffer: buffer_entity.clone(),
 5001            new_language: Some(new_language),
 5002        })
 5003    }
 5004
 5005    pub fn buffer_store(&self) -> Entity<BufferStore> {
 5006        self.buffer_store.clone()
 5007    }
 5008
 5009    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 5010        self.active_entry = active_entry;
 5011    }
 5012
 5013    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 5014        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 5015            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 5016        {
 5017            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 5018                summaries
 5019                    .iter()
 5020                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 5021            });
 5022            if let Some(summary) = summaries.next() {
 5023                client
 5024                    .send(proto::UpdateDiagnosticSummary {
 5025                        project_id: downstream_project_id,
 5026                        worktree_id: worktree.id().to_proto(),
 5027                        summary: Some(summary),
 5028                        more_summaries: summaries.collect(),
 5029                    })
 5030                    .log_err();
 5031            }
 5032        }
 5033    }
 5034
 5035    fn is_capable_for_proto_request<R>(
 5036        &self,
 5037        buffer: &Entity<Buffer>,
 5038        request: &R,
 5039        cx: &App,
 5040    ) -> bool
 5041    where
 5042        R: LspCommand,
 5043    {
 5044        self.check_if_capable_for_proto_request(
 5045            buffer,
 5046            |capabilities| {
 5047                request.check_capabilities(AdapterServerCapabilities {
 5048                    server_capabilities: capabilities.clone(),
 5049                    code_action_kinds: None,
 5050                })
 5051            },
 5052            cx,
 5053        )
 5054    }
 5055
 5056    fn relevant_server_ids_for_capability_check(
 5057        &self,
 5058        buffer: &Entity<Buffer>,
 5059        cx: &App,
 5060    ) -> Vec<LanguageServerId> {
 5061        let buffer_id = buffer.read(cx).remote_id();
 5062        if let Some(local) = self.as_local() {
 5063            return local
 5064                .buffers_opened_in_servers
 5065                .get(&buffer_id)
 5066                .into_iter()
 5067                .flatten()
 5068                .copied()
 5069                .collect();
 5070        }
 5071
 5072        let Some(language) = buffer.read(cx).language().cloned() else {
 5073            return Vec::default();
 5074        };
 5075        let registered_language_servers = self
 5076            .languages
 5077            .lsp_adapters(&language.name())
 5078            .into_iter()
 5079            .map(|lsp_adapter| lsp_adapter.name())
 5080            .collect::<HashSet<_>>();
 5081        self.language_server_statuses
 5082            .iter()
 5083            .filter_map(|(server_id, server_status)| {
 5084                // Include servers that are either registered for this language OR
 5085                // available to be loaded (for SSH remote mode where adapters like
 5086                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 5087                // but only loaded on the server side)
 5088                let is_relevant = registered_language_servers.contains(&server_status.name)
 5089                    || self.languages.is_lsp_adapter_available(&server_status.name);
 5090                is_relevant.then_some(*server_id)
 5091            })
 5092            .collect()
 5093    }
 5094
 5095    fn check_if_any_relevant_server_matches<F>(
 5096        &self,
 5097        buffer: &Entity<Buffer>,
 5098        mut check: F,
 5099        cx: &App,
 5100    ) -> bool
 5101    where
 5102        F: FnMut(&LanguageServerStatus, &lsp::ServerCapabilities) -> bool,
 5103    {
 5104        self.relevant_server_ids_for_capability_check(buffer, cx)
 5105            .into_iter()
 5106            .filter_map(|server_id| {
 5107                Some((
 5108                    self.language_server_statuses.get(&server_id)?,
 5109                    self.lsp_server_capabilities.get(&server_id)?,
 5110                ))
 5111            })
 5112            .any(|(server_status, capabilities)| check(server_status, capabilities))
 5113    }
 5114
 5115    fn check_if_capable_for_proto_request<F>(
 5116        &self,
 5117        buffer: &Entity<Buffer>,
 5118        mut check: F,
 5119        cx: &App,
 5120    ) -> bool
 5121    where
 5122        F: FnMut(&lsp::ServerCapabilities) -> bool,
 5123    {
 5124        self.check_if_any_relevant_server_matches(buffer, |_, capabilities| check(capabilities), cx)
 5125    }
 5126
 5127    pub fn supports_range_formatting(&self, buffer: &Entity<Buffer>, cx: &App) -> bool {
 5128        let settings = LanguageSettings::for_buffer(buffer.read(cx), cx);
 5129        settings.formatter.as_ref().iter().any(|formatter| {
 5130            match formatter {
 5131                Formatter::None => false,
 5132                Formatter::Auto => {
 5133                    settings.prettier.allowed
 5134                        || self.check_if_capable_for_proto_request(
 5135                            buffer,
 5136                            server_capabilities_support_range_formatting,
 5137                            cx,
 5138                        )
 5139                }
 5140                Formatter::Prettier => true,
 5141                Formatter::External { .. } => false,
 5142                Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current) => {
 5143                    self.check_if_capable_for_proto_request(
 5144                        buffer,
 5145                        server_capabilities_support_range_formatting,
 5146                        cx,
 5147                    )
 5148                }
 5149                Formatter::LanguageServer(
 5150                    settings::LanguageServerFormatterSpecifier::Specific { name },
 5151                ) => self.check_if_any_relevant_server_matches(
 5152                    buffer,
 5153                    |server_status, capabilities| {
 5154                        server_status.name.0.as_ref() == name
 5155                            && server_capabilities_support_range_formatting(capabilities)
 5156                    },
 5157                    cx,
 5158                ),
 5159                // `FormatSelections` should only surface when a formatter can honor the
 5160                // selected ranges. Code actions can still run as part of formatting, but
 5161                // they operate on the whole buffer rather than the selected text.
 5162                Formatter::CodeAction(_) => false,
 5163            }
 5164        })
 5165    }
 5166
 5167    fn all_capable_for_proto_request<F>(
 5168        &self,
 5169        buffer: &Entity<Buffer>,
 5170        mut check: F,
 5171        cx: &App,
 5172    ) -> Vec<(lsp::LanguageServerId, lsp::LanguageServerName)>
 5173    where
 5174        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 5175    {
 5176        self.relevant_server_ids_for_capability_check(buffer, cx)
 5177            .into_iter()
 5178            .filter_map(|server_id| {
 5179                Some((
 5180                    server_id,
 5181                    &self.language_server_statuses.get(&server_id)?.name,
 5182                    self.lsp_server_capabilities.get(&server_id)?,
 5183                ))
 5184            })
 5185            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 5186            .map(|(server_id, server_name, _)| (server_id, server_name.clone()))
 5187            .collect()
 5188    }
 5189
 5190    pub fn request_lsp<R>(
 5191        &mut self,
 5192        buffer: Entity<Buffer>,
 5193        server: LanguageServerToQuery,
 5194        request: R,
 5195        cx: &mut Context<Self>,
 5196    ) -> Task<Result<R::Response>>
 5197    where
 5198        R: LspCommand,
 5199        <R::LspRequest as lsp::request::Request>::Result: Send,
 5200        <R::LspRequest as lsp::request::Request>::Params: Send,
 5201    {
 5202        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 5203            return self.send_lsp_proto_request(
 5204                buffer,
 5205                upstream_client,
 5206                upstream_project_id,
 5207                request,
 5208                cx,
 5209            );
 5210        }
 5211
 5212        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 5213            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 5214                local
 5215                    .language_servers_for_buffer(buffer, cx)
 5216                    .find(|(_, server)| {
 5217                        request.check_capabilities(server.adapter_server_capabilities())
 5218                    })
 5219                    .map(|(_, server)| server.clone())
 5220            }),
 5221            LanguageServerToQuery::Other(id) => self
 5222                .language_server_for_local_buffer(buffer, id, cx)
 5223                .and_then(|(_, server)| {
 5224                    request
 5225                        .check_capabilities(server.adapter_server_capabilities())
 5226                        .then(|| Arc::clone(server))
 5227                }),
 5228        }) else {
 5229            return Task::ready(Ok(Default::default()));
 5230        };
 5231
 5232        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 5233
 5234        let Some(file) = file else {
 5235            return Task::ready(Ok(Default::default()));
 5236        };
 5237
 5238        let lsp_params = match request.to_lsp_params_or_response(
 5239            &file.abs_path(cx),
 5240            buffer.read(cx),
 5241            &language_server,
 5242            cx,
 5243        ) {
 5244            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 5245            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 5246            Err(err) => {
 5247                let message = format!(
 5248                    "{} via {} failed: {}",
 5249                    request.display_name(),
 5250                    language_server.name(),
 5251                    err
 5252                );
 5253                // rust-analyzer likes to error with this when its still loading up
 5254                if !message.ends_with("content modified") {
 5255                    log::warn!("{message}");
 5256                }
 5257                return Task::ready(Err(anyhow!(message)));
 5258            }
 5259        };
 5260
 5261        let status = request.status();
 5262        let request_timeout = ProjectSettings::get_global(cx)
 5263            .global_lsp_settings
 5264            .get_request_timeout();
 5265
 5266        cx.spawn(async move |this, cx| {
 5267            let lsp_request = language_server.request::<R::LspRequest>(lsp_params, request_timeout);
 5268
 5269            let id = lsp_request.id();
 5270            let _cleanup = if status.is_some() {
 5271                cx.update(|cx| {
 5272                    this.update(cx, |this, cx| {
 5273                        this.on_lsp_work_start(
 5274                            language_server.server_id(),
 5275                            ProgressToken::Number(id),
 5276                            LanguageServerProgress {
 5277                                is_disk_based_diagnostics_progress: false,
 5278                                is_cancellable: false,
 5279                                title: None,
 5280                                message: status.clone(),
 5281                                percentage: None,
 5282                                last_update_at: cx.background_executor().now(),
 5283                            },
 5284                            cx,
 5285                        );
 5286                    })
 5287                })
 5288                .log_err();
 5289
 5290                Some(defer(|| {
 5291                    cx.update(|cx| {
 5292                        this.update(cx, |this, cx| {
 5293                            this.on_lsp_work_end(
 5294                                language_server.server_id(),
 5295                                ProgressToken::Number(id),
 5296                                cx,
 5297                            );
 5298                        })
 5299                    })
 5300                    .log_err();
 5301                }))
 5302            } else {
 5303                None
 5304            };
 5305
 5306            let result = lsp_request.await.into_response();
 5307
 5308            let response = result.map_err(|err| {
 5309                let message = format!(
 5310                    "{} via {} failed: {}",
 5311                    request.display_name(),
 5312                    language_server.name(),
 5313                    err
 5314                );
 5315                // rust-analyzer likes to error with this when its still loading up
 5316                if !message.ends_with("content modified") {
 5317                    log::warn!("{message}");
 5318                }
 5319                anyhow::anyhow!(message)
 5320            })?;
 5321
 5322            request
 5323                .response_from_lsp(
 5324                    response,
 5325                    this.upgrade().context("no app context")?,
 5326                    buffer,
 5327                    language_server.server_id(),
 5328                    cx.clone(),
 5329                )
 5330                .await
 5331        })
 5332    }
 5333
 5334    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 5335        let mut language_formatters_to_check = Vec::new();
 5336        for buffer in self.buffer_store.read(cx).buffers() {
 5337            let buffer = buffer.read(cx);
 5338            let settings = LanguageSettings::for_buffer(buffer, cx);
 5339            if buffer.language().is_some() {
 5340                let buffer_file = File::from_dyn(buffer.file());
 5341                language_formatters_to_check.push((
 5342                    buffer_file.map(|f| f.worktree_id(cx)),
 5343                    settings.into_owned(),
 5344                ));
 5345            }
 5346        }
 5347
 5348        self.request_workspace_config_refresh();
 5349
 5350        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 5351            prettier_store.update(cx, |prettier_store, cx| {
 5352                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 5353            })
 5354        }
 5355
 5356        let new_semantic_token_rules = crate::project_settings::ProjectSettings::get_global(cx)
 5357            .global_lsp_settings
 5358            .semantic_token_rules
 5359            .clone();
 5360        self.semantic_token_config
 5361            .update_rules(new_semantic_token_rules);
 5362        // Always clear cached stylizers so that changes to language-specific
 5363        // semantic token rules (e.g. from extension install/uninstall) are
 5364        // picked up. Stylizers are recreated lazily, so this is cheap.
 5365        self.semantic_token_config.clear_stylizers();
 5366
 5367        let new_global_semantic_tokens_mode =
 5368            all_language_settings(None, cx).defaults.semantic_tokens;
 5369        if self
 5370            .semantic_token_config
 5371            .update_global_mode(new_global_semantic_tokens_mode)
 5372        {
 5373            self.restart_all_language_servers(cx);
 5374        }
 5375
 5376        cx.notify();
 5377    }
 5378
 5379    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 5380        let buffer_store = self.buffer_store.clone();
 5381        let Some(local) = self.as_local_mut() else {
 5382            return;
 5383        };
 5384        let mut adapters = BTreeMap::default();
 5385        let get_adapter = {
 5386            let languages = local.languages.clone();
 5387            let environment = local.environment.clone();
 5388            let weak = local.weak.clone();
 5389            let worktree_store = local.worktree_store.clone();
 5390            let http_client = local.http_client.clone();
 5391            let fs = local.fs.clone();
 5392            move |worktree_id, cx: &mut App| {
 5393                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 5394                Some(LocalLspAdapterDelegate::new(
 5395                    languages.clone(),
 5396                    &environment,
 5397                    weak.clone(),
 5398                    &worktree,
 5399                    http_client.clone(),
 5400                    fs.clone(),
 5401                    cx,
 5402                ))
 5403            }
 5404        };
 5405
 5406        let mut messages_to_report = Vec::new();
 5407        let (new_tree, to_stop) = {
 5408            let mut rebase = local.lsp_tree.rebase();
 5409            let buffers = buffer_store
 5410                .read(cx)
 5411                .buffers()
 5412                .filter_map(|buffer| {
 5413                    let raw_buffer = buffer.read(cx);
 5414                    if !local
 5415                        .registered_buffers
 5416                        .contains_key(&raw_buffer.remote_id())
 5417                    {
 5418                        return None;
 5419                    }
 5420                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5421                    let language = raw_buffer.language().cloned()?;
 5422                    Some((file, language, raw_buffer.remote_id()))
 5423                })
 5424                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5425            for (file, language, buffer_id) in buffers {
 5426                let worktree_id = file.worktree_id(cx);
 5427                let Some(worktree) = local
 5428                    .worktree_store
 5429                    .read(cx)
 5430                    .worktree_for_id(worktree_id, cx)
 5431                else {
 5432                    continue;
 5433                };
 5434
 5435                if let Some((_, apply)) = local.reuse_existing_language_server(
 5436                    rebase.server_tree(),
 5437                    &worktree,
 5438                    &language.name(),
 5439                    cx,
 5440                ) {
 5441                    (apply)(rebase.server_tree());
 5442                } else if let Some(lsp_delegate) = adapters
 5443                    .entry(worktree_id)
 5444                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5445                    .clone()
 5446                {
 5447                    let delegate =
 5448                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5449                    let path = file
 5450                        .path()
 5451                        .parent()
 5452                        .map(Arc::from)
 5453                        .unwrap_or_else(|| file.path().clone());
 5454                    let worktree_path = ProjectPath { worktree_id, path };
 5455                    let abs_path = file.abs_path(cx);
 5456                    let nodes = rebase
 5457                        .walk(
 5458                            worktree_path,
 5459                            language.name(),
 5460                            language.manifest(),
 5461                            delegate.clone(),
 5462                            cx,
 5463                        )
 5464                        .collect::<Vec<_>>();
 5465                    for node in nodes {
 5466                        let server_id = node.server_id_or_init(|disposition| {
 5467                            let path = &disposition.path;
 5468                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5469                            let key = LanguageServerSeed {
 5470                                worktree_id,
 5471                                name: disposition.server_name.clone(),
 5472                                settings: LanguageServerSeedSettings {
 5473                                    binary: disposition.settings.binary.clone(),
 5474                                    initialization_options: disposition
 5475                                        .settings
 5476                                        .initialization_options
 5477                                        .clone(),
 5478                                },
 5479                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5480                                    path.worktree_id,
 5481                                    &path.path,
 5482                                    language.name(),
 5483                                ),
 5484                            };
 5485                            local.language_server_ids.remove(&key);
 5486
 5487                            let server_id = local.get_or_insert_language_server(
 5488                                &worktree,
 5489                                lsp_delegate.clone(),
 5490                                disposition,
 5491                                &language.name(),
 5492                                cx,
 5493                            );
 5494                            if let Some(state) = local.language_servers.get(&server_id)
 5495                                && let Ok(uri) = uri
 5496                            {
 5497                                state.add_workspace_folder(uri);
 5498                            };
 5499                            server_id
 5500                        });
 5501
 5502                        if let Some(language_server_id) = server_id {
 5503                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5504                                language_server_id,
 5505                                name: node.name(),
 5506                                message:
 5507                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5508                                        proto::RegisteredForBuffer {
 5509                                            buffer_abs_path: abs_path
 5510                                                .to_string_lossy()
 5511                                                .into_owned(),
 5512                                            buffer_id: buffer_id.to_proto(),
 5513                                        },
 5514                                    ),
 5515                            });
 5516                        }
 5517                    }
 5518                } else {
 5519                    continue;
 5520                }
 5521            }
 5522            rebase.finish()
 5523        };
 5524        for message in messages_to_report {
 5525            cx.emit(message);
 5526        }
 5527        local.lsp_tree = new_tree;
 5528        for (id, _) in to_stop {
 5529            self.stop_local_language_server(id, cx).detach();
 5530        }
 5531    }
 5532
 5533    pub fn apply_code_action(
 5534        &self,
 5535        buffer_handle: Entity<Buffer>,
 5536        mut action: CodeAction,
 5537        push_to_history: bool,
 5538        cx: &mut Context<Self>,
 5539    ) -> Task<Result<ProjectTransaction>> {
 5540        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5541            let request = proto::ApplyCodeAction {
 5542                project_id,
 5543                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5544                action: Some(Self::serialize_code_action(&action)),
 5545            };
 5546            let buffer_store = self.buffer_store();
 5547            cx.spawn(async move |_, cx| {
 5548                let response = upstream_client
 5549                    .request(request)
 5550                    .await?
 5551                    .transaction
 5552                    .context("missing transaction")?;
 5553
 5554                buffer_store
 5555                    .update(cx, |buffer_store, cx| {
 5556                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5557                    })
 5558                    .await
 5559            })
 5560        } else if self.mode.is_local() {
 5561            let Some((_, lang_server, request_timeout)) = buffer_handle.update(cx, |buffer, cx| {
 5562                let request_timeout = ProjectSettings::get_global(cx)
 5563                    .global_lsp_settings
 5564                    .get_request_timeout();
 5565                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5566                    .map(|(adapter, server)| (adapter.clone(), server.clone(), request_timeout))
 5567            }) else {
 5568                return Task::ready(Ok(ProjectTransaction::default()));
 5569            };
 5570
 5571            cx.spawn(async move |this, cx| {
 5572                LocalLspStore::try_resolve_code_action(&lang_server, &mut action, request_timeout)
 5573                    .await
 5574                    .context("resolving a code action")?;
 5575                if let Some(edit) = action.lsp_action.edit()
 5576                    && (edit.changes.is_some() || edit.document_changes.is_some())
 5577                {
 5578                    return LocalLspStore::deserialize_workspace_edit(
 5579                        this.upgrade().context("no app present")?,
 5580                        edit.clone(),
 5581                        push_to_history,
 5582                        lang_server.clone(),
 5583                        cx,
 5584                    )
 5585                    .await;
 5586                }
 5587
 5588                let Some(command) = action.lsp_action.command() else {
 5589                    return Ok(ProjectTransaction::default());
 5590                };
 5591
 5592                let server_capabilities = lang_server.capabilities();
 5593                let available_commands = server_capabilities
 5594                    .execute_command_provider
 5595                    .as_ref()
 5596                    .map(|options| options.commands.as_slice())
 5597                    .unwrap_or_default();
 5598
 5599                if !available_commands.contains(&command.command) {
 5600                    log::warn!(
 5601                        "Skipping executeCommand for {}, not listed in language server capabilities",
 5602                        command.command
 5603                    );
 5604                    return Ok(ProjectTransaction::default());
 5605                }
 5606
 5607                let request_timeout = cx.update(|app| {
 5608                    ProjectSettings::get_global(app)
 5609                        .global_lsp_settings
 5610                        .get_request_timeout()
 5611                });
 5612
 5613                this.update(cx, |this, _| {
 5614                    this.as_local_mut()
 5615                        .unwrap()
 5616                        .last_workspace_edits_by_language_server
 5617                        .remove(&lang_server.server_id());
 5618                })?;
 5619
 5620                let _result = lang_server
 5621                    .request::<lsp::request::ExecuteCommand>(
 5622                        lsp::ExecuteCommandParams {
 5623                            command: command.command.clone(),
 5624                            arguments: command.arguments.clone().unwrap_or_default(),
 5625                            ..lsp::ExecuteCommandParams::default()
 5626                        },
 5627                        request_timeout,
 5628                    )
 5629                    .await
 5630                    .into_response()
 5631                    .context("execute command")?;
 5632
 5633                return this.update(cx, |this, _| {
 5634                    this.as_local_mut()
 5635                        .unwrap()
 5636                        .last_workspace_edits_by_language_server
 5637                        .remove(&lang_server.server_id())
 5638                        .unwrap_or_default()
 5639                });
 5640            })
 5641        } else {
 5642            Task::ready(Err(anyhow!("no upstream client and not local")))
 5643        }
 5644    }
 5645
 5646    pub fn apply_code_action_kind(
 5647        &mut self,
 5648        buffers: HashSet<Entity<Buffer>>,
 5649        kind: CodeActionKind,
 5650        push_to_history: bool,
 5651        cx: &mut Context<Self>,
 5652    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5653        if self.as_local().is_some() {
 5654            cx.spawn(async move |lsp_store, cx| {
 5655                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5656                let result = LocalLspStore::execute_code_action_kind_locally(
 5657                    lsp_store.clone(),
 5658                    buffers,
 5659                    kind,
 5660                    push_to_history,
 5661                    cx,
 5662                )
 5663                .await;
 5664                lsp_store.update(cx, |lsp_store, _| {
 5665                    lsp_store.update_last_formatting_failure(&result);
 5666                })?;
 5667                result
 5668            })
 5669        } else if let Some((client, project_id)) = self.upstream_client() {
 5670            let buffer_store = self.buffer_store();
 5671            cx.spawn(async move |lsp_store, cx| {
 5672                let result = client
 5673                    .request(proto::ApplyCodeActionKind {
 5674                        project_id,
 5675                        kind: kind.as_str().to_owned(),
 5676                        buffer_ids: buffers
 5677                            .iter()
 5678                            .map(|buffer| {
 5679                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5680                            })
 5681                            .collect(),
 5682                    })
 5683                    .await
 5684                    .and_then(|result| result.transaction.context("missing transaction"));
 5685                lsp_store.update(cx, |lsp_store, _| {
 5686                    lsp_store.update_last_formatting_failure(&result);
 5687                })?;
 5688
 5689                let transaction_response = result?;
 5690                buffer_store
 5691                    .update(cx, |buffer_store, cx| {
 5692                        buffer_store.deserialize_project_transaction(
 5693                            transaction_response,
 5694                            push_to_history,
 5695                            cx,
 5696                        )
 5697                    })
 5698                    .await
 5699            })
 5700        } else {
 5701            Task::ready(Ok(ProjectTransaction::default()))
 5702        }
 5703    }
 5704
 5705    pub fn resolved_hint(
 5706        &mut self,
 5707        buffer_id: BufferId,
 5708        id: InlayId,
 5709        cx: &mut Context<Self>,
 5710    ) -> Option<ResolvedHint> {
 5711        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5712
 5713        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5714        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5715        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5716        let (server_id, resolve_data) = match &hint.resolve_state {
 5717            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5718            ResolveState::Resolving => {
 5719                return Some(ResolvedHint::Resolving(
 5720                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5721                ));
 5722            }
 5723            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5724        };
 5725
 5726        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5727        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5728        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5729            id,
 5730            cx.spawn(async move |lsp_store, cx| {
 5731                let resolved_hint = resolve_task.await;
 5732                lsp_store
 5733                    .update(cx, |lsp_store, _| {
 5734                        if let Some(old_inlay_hint) = lsp_store
 5735                            .lsp_data
 5736                            .get_mut(&buffer_id)
 5737                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5738                        {
 5739                            match resolved_hint {
 5740                                Ok(resolved_hint) => {
 5741                                    *old_inlay_hint = resolved_hint;
 5742                                }
 5743                                Err(e) => {
 5744                                    old_inlay_hint.resolve_state =
 5745                                        ResolveState::CanResolve(server_id, resolve_data);
 5746                                    log::error!("Inlay hint resolve failed: {e:#}");
 5747                                }
 5748                            }
 5749                        }
 5750                    })
 5751                    .ok();
 5752            })
 5753            .shared(),
 5754        );
 5755        debug_assert!(
 5756            previous_task.is_none(),
 5757            "Did not change hint's resolve state after spawning its resolve"
 5758        );
 5759        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5760        None
 5761    }
 5762
 5763    pub(crate) fn linked_edits(
 5764        &mut self,
 5765        buffer: &Entity<Buffer>,
 5766        position: Anchor,
 5767        cx: &mut Context<Self>,
 5768    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5769        let snapshot = buffer.read(cx).snapshot();
 5770        let scope = snapshot.language_scope_at(position);
 5771        let Some(server_id) = self
 5772            .as_local()
 5773            .and_then(|local| {
 5774                buffer.update(cx, |buffer, cx| {
 5775                    local
 5776                        .language_servers_for_buffer(buffer, cx)
 5777                        .filter(|(_, server)| {
 5778                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5779                        })
 5780                        .filter(|(adapter, _)| {
 5781                            scope
 5782                                .as_ref()
 5783                                .map(|scope| scope.language_allowed(&adapter.name))
 5784                                .unwrap_or(true)
 5785                        })
 5786                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5787                        .next()
 5788                })
 5789            })
 5790            .or_else(|| {
 5791                self.upstream_client()
 5792                    .is_some()
 5793                    .then_some(LanguageServerToQuery::FirstCapable)
 5794            })
 5795            .filter(|_| {
 5796                maybe!({
 5797                    buffer.read(cx).language_at(position)?;
 5798                    Some(
 5799                        LanguageSettings::for_buffer_at(&buffer.read(cx), position, cx)
 5800                            .linked_edits,
 5801                    )
 5802                }) == Some(true)
 5803            })
 5804        else {
 5805            return Task::ready(Ok(Vec::new()));
 5806        };
 5807
 5808        self.request_lsp(
 5809            buffer.clone(),
 5810            server_id,
 5811            LinkedEditingRange { position },
 5812            cx,
 5813        )
 5814    }
 5815
 5816    fn apply_on_type_formatting(
 5817        &mut self,
 5818        buffer: Entity<Buffer>,
 5819        position: Anchor,
 5820        trigger: String,
 5821        cx: &mut Context<Self>,
 5822    ) -> Task<Result<Option<Transaction>>> {
 5823        if let Some((client, project_id)) = self.upstream_client() {
 5824            if !self.check_if_capable_for_proto_request(
 5825                &buffer,
 5826                |capabilities| {
 5827                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5828                },
 5829                cx,
 5830            ) {
 5831                return Task::ready(Ok(None));
 5832            }
 5833            let request = proto::OnTypeFormatting {
 5834                project_id,
 5835                buffer_id: buffer.read(cx).remote_id().into(),
 5836                position: Some(serialize_anchor(&position)),
 5837                trigger,
 5838                version: serialize_version(&buffer.read(cx).version()),
 5839            };
 5840            cx.background_spawn(async move {
 5841                client
 5842                    .request(request)
 5843                    .await?
 5844                    .transaction
 5845                    .map(language::proto::deserialize_transaction)
 5846                    .transpose()
 5847            })
 5848        } else if let Some(local) = self.as_local_mut() {
 5849            let buffer_id = buffer.read(cx).remote_id();
 5850            local.buffers_being_formatted.insert(buffer_id);
 5851            cx.spawn(async move |this, cx| {
 5852                let _cleanup = defer({
 5853                    let this = this.clone();
 5854                    let mut cx = cx.clone();
 5855                    move || {
 5856                        this.update(&mut cx, |this, _| {
 5857                            if let Some(local) = this.as_local_mut() {
 5858                                local.buffers_being_formatted.remove(&buffer_id);
 5859                            }
 5860                        })
 5861                        .ok();
 5862                    }
 5863                });
 5864
 5865                buffer
 5866                    .update(cx, |buffer, _| {
 5867                        buffer.wait_for_edits(Some(position.timestamp()))
 5868                    })
 5869                    .await?;
 5870                this.update(cx, |this, cx| {
 5871                    let position = position.to_point_utf16(buffer.read(cx));
 5872                    this.on_type_format(buffer, position, trigger, false, cx)
 5873                })?
 5874                .await
 5875            })
 5876        } else {
 5877            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5878        }
 5879    }
 5880
 5881    pub fn on_type_format<T: ToPointUtf16>(
 5882        &mut self,
 5883        buffer: Entity<Buffer>,
 5884        position: T,
 5885        trigger: String,
 5886        push_to_history: bool,
 5887        cx: &mut Context<Self>,
 5888    ) -> Task<Result<Option<Transaction>>> {
 5889        let position = position.to_point_utf16(buffer.read(cx));
 5890        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5891    }
 5892
 5893    fn on_type_format_impl(
 5894        &mut self,
 5895        buffer: Entity<Buffer>,
 5896        position: PointUtf16,
 5897        trigger: String,
 5898        push_to_history: bool,
 5899        cx: &mut Context<Self>,
 5900    ) -> Task<Result<Option<Transaction>>> {
 5901        let options = buffer.update(cx, |buffer, cx| {
 5902            lsp_command::lsp_formatting_options(
 5903                LanguageSettings::for_buffer_at(buffer, position, cx).as_ref(),
 5904            )
 5905        });
 5906
 5907        cx.spawn(async move |this, cx| {
 5908            if let Some(waiter) =
 5909                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5910            {
 5911                waiter.await?;
 5912            }
 5913            cx.update(|cx| {
 5914                this.update(cx, |this, cx| {
 5915                    this.request_lsp(
 5916                        buffer.clone(),
 5917                        LanguageServerToQuery::FirstCapable,
 5918                        OnTypeFormatting {
 5919                            position,
 5920                            trigger,
 5921                            options,
 5922                            push_to_history,
 5923                        },
 5924                        cx,
 5925                    )
 5926                })
 5927            })?
 5928            .await
 5929        })
 5930    }
 5931
 5932    pub fn definitions(
 5933        &mut self,
 5934        buffer: &Entity<Buffer>,
 5935        position: PointUtf16,
 5936        cx: &mut Context<Self>,
 5937    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5938        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5939            let request = GetDefinitions { position };
 5940            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5941                return Task::ready(Ok(None));
 5942            }
 5943
 5944            let request_timeout = ProjectSettings::get_global(cx)
 5945                .global_lsp_settings
 5946                .get_request_timeout();
 5947
 5948            let request_task = upstream_client.request_lsp(
 5949                project_id,
 5950                None,
 5951                request_timeout,
 5952                cx.background_executor().clone(),
 5953                request.to_proto(project_id, buffer.read(cx)),
 5954            );
 5955            let buffer = buffer.clone();
 5956            cx.spawn(async move |weak_lsp_store, cx| {
 5957                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5958                    return Ok(None);
 5959                };
 5960                let Some(responses) = request_task.await? else {
 5961                    return Ok(None);
 5962                };
 5963                let actions = join_all(responses.payload.into_iter().map(|response| {
 5964                    GetDefinitions { position }.response_from_proto(
 5965                        response.response,
 5966                        lsp_store.clone(),
 5967                        buffer.clone(),
 5968                        cx.clone(),
 5969                    )
 5970                }))
 5971                .await;
 5972
 5973                Ok(Some(
 5974                    actions
 5975                        .into_iter()
 5976                        .collect::<Result<Vec<Vec<_>>>>()?
 5977                        .into_iter()
 5978                        .flatten()
 5979                        .dedup()
 5980                        .collect(),
 5981                ))
 5982            })
 5983        } else {
 5984            let definitions_task = self.request_multiple_lsp_locally(
 5985                buffer,
 5986                Some(position),
 5987                GetDefinitions { position },
 5988                cx,
 5989            );
 5990            cx.background_spawn(async move {
 5991                Ok(Some(
 5992                    definitions_task
 5993                        .await
 5994                        .into_iter()
 5995                        .flat_map(|(_, definitions)| definitions)
 5996                        .dedup()
 5997                        .collect(),
 5998                ))
 5999            })
 6000        }
 6001    }
 6002
 6003    pub fn declarations(
 6004        &mut self,
 6005        buffer: &Entity<Buffer>,
 6006        position: PointUtf16,
 6007        cx: &mut Context<Self>,
 6008    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6009        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6010            let request = GetDeclarations { position };
 6011            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6012                return Task::ready(Ok(None));
 6013            }
 6014            let request_timeout = ProjectSettings::get_global(cx)
 6015                .global_lsp_settings
 6016                .get_request_timeout();
 6017            let request_task = upstream_client.request_lsp(
 6018                project_id,
 6019                None,
 6020                request_timeout,
 6021                cx.background_executor().clone(),
 6022                request.to_proto(project_id, buffer.read(cx)),
 6023            );
 6024            let buffer = buffer.clone();
 6025            cx.spawn(async move |weak_lsp_store, cx| {
 6026                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6027                    return Ok(None);
 6028                };
 6029                let Some(responses) = request_task.await? else {
 6030                    return Ok(None);
 6031                };
 6032                let actions = join_all(responses.payload.into_iter().map(|response| {
 6033                    GetDeclarations { position }.response_from_proto(
 6034                        response.response,
 6035                        lsp_store.clone(),
 6036                        buffer.clone(),
 6037                        cx.clone(),
 6038                    )
 6039                }))
 6040                .await;
 6041
 6042                Ok(Some(
 6043                    actions
 6044                        .into_iter()
 6045                        .collect::<Result<Vec<Vec<_>>>>()?
 6046                        .into_iter()
 6047                        .flatten()
 6048                        .dedup()
 6049                        .collect(),
 6050                ))
 6051            })
 6052        } else {
 6053            let declarations_task = self.request_multiple_lsp_locally(
 6054                buffer,
 6055                Some(position),
 6056                GetDeclarations { position },
 6057                cx,
 6058            );
 6059            cx.background_spawn(async move {
 6060                Ok(Some(
 6061                    declarations_task
 6062                        .await
 6063                        .into_iter()
 6064                        .flat_map(|(_, declarations)| declarations)
 6065                        .dedup()
 6066                        .collect(),
 6067                ))
 6068            })
 6069        }
 6070    }
 6071
 6072    pub fn type_definitions(
 6073        &mut self,
 6074        buffer: &Entity<Buffer>,
 6075        position: PointUtf16,
 6076        cx: &mut Context<Self>,
 6077    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6078        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6079            let request = GetTypeDefinitions { position };
 6080            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6081                return Task::ready(Ok(None));
 6082            }
 6083            let request_timeout = ProjectSettings::get_global(cx)
 6084                .global_lsp_settings
 6085                .get_request_timeout();
 6086            let request_task = upstream_client.request_lsp(
 6087                project_id,
 6088                None,
 6089                request_timeout,
 6090                cx.background_executor().clone(),
 6091                request.to_proto(project_id, buffer.read(cx)),
 6092            );
 6093            let buffer = buffer.clone();
 6094            cx.spawn(async move |weak_lsp_store, cx| {
 6095                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6096                    return Ok(None);
 6097                };
 6098                let Some(responses) = request_task.await? else {
 6099                    return Ok(None);
 6100                };
 6101                let actions = join_all(responses.payload.into_iter().map(|response| {
 6102                    GetTypeDefinitions { position }.response_from_proto(
 6103                        response.response,
 6104                        lsp_store.clone(),
 6105                        buffer.clone(),
 6106                        cx.clone(),
 6107                    )
 6108                }))
 6109                .await;
 6110
 6111                Ok(Some(
 6112                    actions
 6113                        .into_iter()
 6114                        .collect::<Result<Vec<Vec<_>>>>()?
 6115                        .into_iter()
 6116                        .flatten()
 6117                        .dedup()
 6118                        .collect(),
 6119                ))
 6120            })
 6121        } else {
 6122            let type_definitions_task = self.request_multiple_lsp_locally(
 6123                buffer,
 6124                Some(position),
 6125                GetTypeDefinitions { position },
 6126                cx,
 6127            );
 6128            cx.background_spawn(async move {
 6129                Ok(Some(
 6130                    type_definitions_task
 6131                        .await
 6132                        .into_iter()
 6133                        .flat_map(|(_, type_definitions)| type_definitions)
 6134                        .dedup()
 6135                        .collect(),
 6136                ))
 6137            })
 6138        }
 6139    }
 6140
 6141    pub fn implementations(
 6142        &mut self,
 6143        buffer: &Entity<Buffer>,
 6144        position: PointUtf16,
 6145        cx: &mut Context<Self>,
 6146    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 6147        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6148            let request = GetImplementations { position };
 6149            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6150                return Task::ready(Ok(None));
 6151            }
 6152
 6153            let request_timeout = ProjectSettings::get_global(cx)
 6154                .global_lsp_settings
 6155                .get_request_timeout();
 6156            let request_task = upstream_client.request_lsp(
 6157                project_id,
 6158                None,
 6159                request_timeout,
 6160                cx.background_executor().clone(),
 6161                request.to_proto(project_id, buffer.read(cx)),
 6162            );
 6163            let buffer = buffer.clone();
 6164            cx.spawn(async move |weak_lsp_store, cx| {
 6165                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6166                    return Ok(None);
 6167                };
 6168                let Some(responses) = request_task.await? else {
 6169                    return Ok(None);
 6170                };
 6171                let actions = join_all(responses.payload.into_iter().map(|response| {
 6172                    GetImplementations { position }.response_from_proto(
 6173                        response.response,
 6174                        lsp_store.clone(),
 6175                        buffer.clone(),
 6176                        cx.clone(),
 6177                    )
 6178                }))
 6179                .await;
 6180
 6181                Ok(Some(
 6182                    actions
 6183                        .into_iter()
 6184                        .collect::<Result<Vec<Vec<_>>>>()?
 6185                        .into_iter()
 6186                        .flatten()
 6187                        .dedup()
 6188                        .collect(),
 6189                ))
 6190            })
 6191        } else {
 6192            let implementations_task = self.request_multiple_lsp_locally(
 6193                buffer,
 6194                Some(position),
 6195                GetImplementations { position },
 6196                cx,
 6197            );
 6198            cx.background_spawn(async move {
 6199                Ok(Some(
 6200                    implementations_task
 6201                        .await
 6202                        .into_iter()
 6203                        .flat_map(|(_, implementations)| implementations)
 6204                        .dedup()
 6205                        .collect(),
 6206                ))
 6207            })
 6208        }
 6209    }
 6210
 6211    pub fn references(
 6212        &mut self,
 6213        buffer: &Entity<Buffer>,
 6214        position: PointUtf16,
 6215        cx: &mut Context<Self>,
 6216    ) -> Task<Result<Option<Vec<Location>>>> {
 6217        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6218            let request = GetReferences { position };
 6219            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6220                return Task::ready(Ok(None));
 6221            }
 6222
 6223            let request_timeout = ProjectSettings::get_global(cx)
 6224                .global_lsp_settings
 6225                .get_request_timeout();
 6226            let request_task = upstream_client.request_lsp(
 6227                project_id,
 6228                None,
 6229                request_timeout,
 6230                cx.background_executor().clone(),
 6231                request.to_proto(project_id, buffer.read(cx)),
 6232            );
 6233            let buffer = buffer.clone();
 6234            cx.spawn(async move |weak_lsp_store, cx| {
 6235                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6236                    return Ok(None);
 6237                };
 6238                let Some(responses) = request_task.await? else {
 6239                    return Ok(None);
 6240                };
 6241
 6242                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 6243                    GetReferences { position }.response_from_proto(
 6244                        lsp_response.response,
 6245                        lsp_store.clone(),
 6246                        buffer.clone(),
 6247                        cx.clone(),
 6248                    )
 6249                }))
 6250                .await
 6251                .into_iter()
 6252                .collect::<Result<Vec<Vec<_>>>>()?
 6253                .into_iter()
 6254                .flatten()
 6255                .dedup()
 6256                .collect();
 6257                Ok(Some(locations))
 6258            })
 6259        } else {
 6260            let references_task = self.request_multiple_lsp_locally(
 6261                buffer,
 6262                Some(position),
 6263                GetReferences { position },
 6264                cx,
 6265            );
 6266            cx.background_spawn(async move {
 6267                Ok(Some(
 6268                    references_task
 6269                        .await
 6270                        .into_iter()
 6271                        .flat_map(|(_, references)| references)
 6272                        .dedup()
 6273                        .collect(),
 6274                ))
 6275            })
 6276        }
 6277    }
 6278
 6279    pub fn code_actions(
 6280        &mut self,
 6281        buffer: &Entity<Buffer>,
 6282        range: Range<Anchor>,
 6283        kinds: Option<Vec<CodeActionKind>>,
 6284        cx: &mut Context<Self>,
 6285    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 6286        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6287            let request = GetCodeActions {
 6288                range: range.clone(),
 6289                kinds: kinds.clone(),
 6290            };
 6291            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6292                return Task::ready(Ok(None));
 6293            }
 6294            let request_timeout = ProjectSettings::get_global(cx)
 6295                .global_lsp_settings
 6296                .get_request_timeout();
 6297            let request_task = upstream_client.request_lsp(
 6298                project_id,
 6299                None,
 6300                request_timeout,
 6301                cx.background_executor().clone(),
 6302                request.to_proto(project_id, buffer.read(cx)),
 6303            );
 6304            let buffer = buffer.clone();
 6305            cx.spawn(async move |weak_lsp_store, cx| {
 6306                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6307                    return Ok(None);
 6308                };
 6309                let Some(responses) = request_task.await? else {
 6310                    return Ok(None);
 6311                };
 6312                let actions = join_all(responses.payload.into_iter().map(|response| {
 6313                    GetCodeActions {
 6314                        range: range.clone(),
 6315                        kinds: kinds.clone(),
 6316                    }
 6317                    .response_from_proto(
 6318                        response.response,
 6319                        lsp_store.clone(),
 6320                        buffer.clone(),
 6321                        cx.clone(),
 6322                    )
 6323                }))
 6324                .await;
 6325
 6326                Ok(Some(
 6327                    actions
 6328                        .into_iter()
 6329                        .collect::<Result<Vec<Vec<_>>>>()?
 6330                        .into_iter()
 6331                        .flatten()
 6332                        .collect(),
 6333                ))
 6334            })
 6335        } else {
 6336            let all_actions_task = self.request_multiple_lsp_locally(
 6337                buffer,
 6338                Some(range.start),
 6339                GetCodeActions { range, kinds },
 6340                cx,
 6341            );
 6342            cx.background_spawn(async move {
 6343                Ok(Some(
 6344                    all_actions_task
 6345                        .await
 6346                        .into_iter()
 6347                        .flat_map(|(_, actions)| actions)
 6348                        .collect(),
 6349                ))
 6350            })
 6351        }
 6352    }
 6353
 6354    #[inline(never)]
 6355    pub fn completions(
 6356        &self,
 6357        buffer: &Entity<Buffer>,
 6358        position: PointUtf16,
 6359        context: CompletionContext,
 6360        cx: &mut Context<Self>,
 6361    ) -> Task<Result<Vec<CompletionResponse>>> {
 6362        let language_registry = self.languages.clone();
 6363
 6364        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6365            let snapshot = buffer.read(cx).snapshot();
 6366            let offset = position.to_offset(&snapshot);
 6367            let scope = snapshot.language_scope_at(offset);
 6368            let capable_lsps = self.all_capable_for_proto_request(
 6369                buffer,
 6370                |server_name, capabilities| {
 6371                    capabilities.completion_provider.is_some()
 6372                        && scope
 6373                            .as_ref()
 6374                            .map(|scope| scope.language_allowed(server_name))
 6375                            .unwrap_or(true)
 6376                },
 6377                cx,
 6378            );
 6379            if capable_lsps.is_empty() {
 6380                return Task::ready(Ok(Vec::new()));
 6381            }
 6382
 6383            let language = buffer.read(cx).language().cloned();
 6384
 6385            let buffer = buffer.clone();
 6386
 6387            cx.spawn(async move |this, cx| {
 6388                let requests = join_all(
 6389                    capable_lsps
 6390                        .into_iter()
 6391                        .map(|(id, server_name)| {
 6392                            let request = GetCompletions {
 6393                                position,
 6394                                context: context.clone(),
 6395                                server_id: Some(id),
 6396                            };
 6397                            let buffer = buffer.clone();
 6398                            let language = language.clone();
 6399                            let lsp_adapter = language.as_ref().and_then(|language| {
 6400                                let adapters = language_registry.lsp_adapters(&language.name());
 6401                                adapters
 6402                                    .iter()
 6403                                    .find(|adapter| adapter.name() == server_name)
 6404                                    .or_else(|| adapters.first())
 6405                                    .cloned()
 6406                            });
 6407                            let upstream_client = upstream_client.clone();
 6408                            let response = this
 6409                                .update(cx, |this, cx| {
 6410                                    this.send_lsp_proto_request(
 6411                                        buffer,
 6412                                        upstream_client,
 6413                                        project_id,
 6414                                        request,
 6415                                        cx,
 6416                                    )
 6417                                })
 6418                                .log_err();
 6419                            async move {
 6420                                let response = response?.await.log_err()?;
 6421
 6422                                let completions = populate_labels_for_completions(
 6423                                    response.completions,
 6424                                    language,
 6425                                    lsp_adapter,
 6426                                )
 6427                                .await;
 6428
 6429                                Some(CompletionResponse {
 6430                                    completions,
 6431                                    display_options: CompletionDisplayOptions::default(),
 6432                                    is_incomplete: response.is_incomplete,
 6433                                })
 6434                            }
 6435                        })
 6436                        .collect::<Vec<_>>(),
 6437                );
 6438                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6439            })
 6440        } else if let Some(local) = self.as_local() {
 6441            let snapshot = buffer.read(cx).snapshot();
 6442            let offset = position.to_offset(&snapshot);
 6443            let scope = snapshot.language_scope_at(offset);
 6444            let language = snapshot.language().cloned();
 6445            let completion_settings = LanguageSettings::for_buffer(&buffer.read(cx), cx)
 6446                .completions
 6447                .clone();
 6448            if !completion_settings.lsp {
 6449                return Task::ready(Ok(Vec::new()));
 6450            }
 6451
 6452            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6453                local
 6454                    .language_servers_for_buffer(buffer, cx)
 6455                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6456                    .filter(|(adapter, _)| {
 6457                        scope
 6458                            .as_ref()
 6459                            .map(|scope| scope.language_allowed(&adapter.name))
 6460                            .unwrap_or(true)
 6461                    })
 6462                    .map(|(_, server)| server.server_id())
 6463                    .collect()
 6464            });
 6465
 6466            let buffer = buffer.clone();
 6467            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6468            let lsp_timeout = if lsp_timeout > 0 {
 6469                Some(Duration::from_millis(lsp_timeout))
 6470            } else {
 6471                None
 6472            };
 6473            cx.spawn(async move |this,  cx| {
 6474                let mut tasks = Vec::with_capacity(server_ids.len());
 6475                this.update(cx, |lsp_store, cx| {
 6476                    for server_id in server_ids {
 6477                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6478                        let lsp_timeout = lsp_timeout
 6479                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6480                        let mut timeout = cx.background_spawn(async move {
 6481                            match lsp_timeout {
 6482                                Some(lsp_timeout) => {
 6483                                    lsp_timeout.await;
 6484                                    true
 6485                                },
 6486                                None => false,
 6487                            }
 6488                        }).fuse();
 6489                        let mut lsp_request = lsp_store.request_lsp(
 6490                            buffer.clone(),
 6491                            LanguageServerToQuery::Other(server_id),
 6492                            GetCompletions {
 6493                                position,
 6494                                context: context.clone(),
 6495                                server_id: Some(server_id),
 6496                            },
 6497                            cx,
 6498                        ).fuse();
 6499                        let new_task = cx.background_spawn(async move {
 6500                            select_biased! {
 6501                                response = lsp_request => anyhow::Ok(Some(response?)),
 6502                                timeout_happened = timeout => {
 6503                                    if timeout_happened {
 6504                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6505                                        Ok(None)
 6506                                    } else {
 6507                                        let completions = lsp_request.await?;
 6508                                        Ok(Some(completions))
 6509                                    }
 6510                                },
 6511                            }
 6512                        });
 6513                        tasks.push((lsp_adapter, new_task));
 6514                    }
 6515                })?;
 6516
 6517                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6518                    let completion_response = task.await.ok()??;
 6519                    let completions = populate_labels_for_completions(
 6520                            completion_response.completions,
 6521                            language.clone(),
 6522                            lsp_adapter,
 6523                        )
 6524                        .await;
 6525                    Some(CompletionResponse {
 6526                        completions,
 6527                        display_options: CompletionDisplayOptions::default(),
 6528                        is_incomplete: completion_response.is_incomplete,
 6529                    })
 6530                });
 6531
 6532                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6533
 6534                Ok(responses.into_iter().flatten().collect())
 6535            })
 6536        } else {
 6537            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6538        }
 6539    }
 6540
 6541    pub fn resolve_completions(
 6542        &self,
 6543        buffer: Entity<Buffer>,
 6544        completion_indices: Vec<usize>,
 6545        completions: Rc<RefCell<Box<[Completion]>>>,
 6546        cx: &mut Context<Self>,
 6547    ) -> Task<Result<bool>> {
 6548        let client = self.upstream_client();
 6549        let buffer_id = buffer.read(cx).remote_id();
 6550        let buffer_snapshot = buffer.read(cx).snapshot();
 6551
 6552        if !self.check_if_capable_for_proto_request(
 6553            &buffer,
 6554            GetCompletions::can_resolve_completions,
 6555            cx,
 6556        ) {
 6557            return Task::ready(Ok(false));
 6558        }
 6559        cx.spawn(async move |lsp_store, cx| {
 6560            let request_timeout = cx.update(|app| {
 6561                ProjectSettings::get_global(app)
 6562                    .global_lsp_settings
 6563                    .get_request_timeout()
 6564            });
 6565
 6566            let mut did_resolve = false;
 6567            if let Some((client, project_id)) = client {
 6568                for completion_index in completion_indices {
 6569                    let server_id = {
 6570                        let completion = &completions.borrow()[completion_index];
 6571                        completion.source.server_id()
 6572                    };
 6573                    if let Some(server_id) = server_id {
 6574                        if Self::resolve_completion_remote(
 6575                            project_id,
 6576                            server_id,
 6577                            buffer_id,
 6578                            completions.clone(),
 6579                            completion_index,
 6580                            client.clone(),
 6581                        )
 6582                        .await
 6583                        .log_err()
 6584                        .is_some()
 6585                        {
 6586                            did_resolve = true;
 6587                        }
 6588                    } else {
 6589                        resolve_word_completion(
 6590                            &buffer_snapshot,
 6591                            &mut completions.borrow_mut()[completion_index],
 6592                        );
 6593                    }
 6594                }
 6595            } else {
 6596                for completion_index in completion_indices {
 6597                    let server_id = {
 6598                        let completion = &completions.borrow()[completion_index];
 6599                        completion.source.server_id()
 6600                    };
 6601                    if let Some(server_id) = server_id {
 6602                        let server_and_adapter = lsp_store
 6603                            .read_with(cx, |lsp_store, _| {
 6604                                let server = lsp_store.language_server_for_id(server_id)?;
 6605                                let adapter =
 6606                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6607                                Some((server, adapter))
 6608                            })
 6609                            .ok()
 6610                            .flatten();
 6611                        let Some((server, adapter)) = server_and_adapter else {
 6612                            continue;
 6613                        };
 6614
 6615                        let resolved = Self::resolve_completion_local(
 6616                            server,
 6617                            completions.clone(),
 6618                            completion_index,
 6619                            request_timeout,
 6620                        )
 6621                        .await
 6622                        .log_err()
 6623                        .is_some();
 6624                        if resolved {
 6625                            Self::regenerate_completion_labels(
 6626                                adapter,
 6627                                &buffer_snapshot,
 6628                                completions.clone(),
 6629                                completion_index,
 6630                            )
 6631                            .await
 6632                            .log_err();
 6633                            did_resolve = true;
 6634                        }
 6635                    } else {
 6636                        resolve_word_completion(
 6637                            &buffer_snapshot,
 6638                            &mut completions.borrow_mut()[completion_index],
 6639                        );
 6640                    }
 6641                }
 6642            }
 6643
 6644            Ok(did_resolve)
 6645        })
 6646    }
 6647
 6648    async fn resolve_completion_local(
 6649        server: Arc<lsp::LanguageServer>,
 6650        completions: Rc<RefCell<Box<[Completion]>>>,
 6651        completion_index: usize,
 6652        request_timeout: Duration,
 6653    ) -> Result<()> {
 6654        let server_id = server.server_id();
 6655        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6656            return Ok(());
 6657        }
 6658
 6659        let request = {
 6660            let completion = &completions.borrow()[completion_index];
 6661            match &completion.source {
 6662                CompletionSource::Lsp {
 6663                    lsp_completion,
 6664                    resolved,
 6665                    server_id: completion_server_id,
 6666                    ..
 6667                } => {
 6668                    if *resolved {
 6669                        return Ok(());
 6670                    }
 6671                    anyhow::ensure!(
 6672                        server_id == *completion_server_id,
 6673                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6674                    );
 6675                    server.request::<lsp::request::ResolveCompletionItem>(
 6676                        *lsp_completion.clone(),
 6677                        request_timeout,
 6678                    )
 6679                }
 6680                CompletionSource::BufferWord { .. }
 6681                | CompletionSource::Dap { .. }
 6682                | CompletionSource::Custom => {
 6683                    return Ok(());
 6684                }
 6685            }
 6686        };
 6687        let resolved_completion = request
 6688            .await
 6689            .into_response()
 6690            .context("resolve completion")?;
 6691
 6692        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6693        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6694
 6695        let mut completions = completions.borrow_mut();
 6696        let completion = &mut completions[completion_index];
 6697        if let CompletionSource::Lsp {
 6698            lsp_completion,
 6699            resolved,
 6700            server_id: completion_server_id,
 6701            ..
 6702        } = &mut completion.source
 6703        {
 6704            if *resolved {
 6705                return Ok(());
 6706            }
 6707            anyhow::ensure!(
 6708                server_id == *completion_server_id,
 6709                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6710            );
 6711            **lsp_completion = resolved_completion;
 6712            *resolved = true;
 6713        }
 6714        Ok(())
 6715    }
 6716
 6717    async fn regenerate_completion_labels(
 6718        adapter: Arc<CachedLspAdapter>,
 6719        snapshot: &BufferSnapshot,
 6720        completions: Rc<RefCell<Box<[Completion]>>>,
 6721        completion_index: usize,
 6722    ) -> Result<()> {
 6723        let completion_item = completions.borrow()[completion_index]
 6724            .source
 6725            .lsp_completion(true)
 6726            .map(Cow::into_owned);
 6727        if let Some(lsp_documentation) = completion_item
 6728            .as_ref()
 6729            .and_then(|completion_item| completion_item.documentation.clone())
 6730        {
 6731            let mut completions = completions.borrow_mut();
 6732            let completion = &mut completions[completion_index];
 6733            completion.documentation = Some(lsp_documentation.into());
 6734        } else {
 6735            let mut completions = completions.borrow_mut();
 6736            let completion = &mut completions[completion_index];
 6737            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6738        }
 6739
 6740        let mut new_label = match completion_item {
 6741            Some(completion_item) => {
 6742                // Some language servers always return `detail` lazily via resolve, regardless of
 6743                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6744                // See: https://github.com/yioneko/vtsls/issues/213
 6745                let language = snapshot.language();
 6746                match language {
 6747                    Some(language) => {
 6748                        adapter
 6749                            .labels_for_completions(
 6750                                std::slice::from_ref(&completion_item),
 6751                                language,
 6752                            )
 6753                            .await?
 6754                    }
 6755                    None => Vec::new(),
 6756                }
 6757                .pop()
 6758                .flatten()
 6759                .unwrap_or_else(|| {
 6760                    CodeLabel::fallback_for_completion(
 6761                        &completion_item,
 6762                        language.map(|language| language.as_ref()),
 6763                    )
 6764                })
 6765            }
 6766            None => CodeLabel::plain(
 6767                completions.borrow()[completion_index].new_text.clone(),
 6768                None,
 6769            ),
 6770        };
 6771        ensure_uniform_list_compatible_label(&mut new_label);
 6772
 6773        let mut completions = completions.borrow_mut();
 6774        let completion = &mut completions[completion_index];
 6775        if completion.label.filter_text() == new_label.filter_text() {
 6776            completion.label = new_label;
 6777        } else {
 6778            log::error!(
 6779                "Resolved completion changed display label from {} to {}. \
 6780                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6781                completion.label.text(),
 6782                new_label.text(),
 6783                completion.label.filter_text(),
 6784                new_label.filter_text()
 6785            );
 6786        }
 6787
 6788        Ok(())
 6789    }
 6790
 6791    async fn resolve_completion_remote(
 6792        project_id: u64,
 6793        server_id: LanguageServerId,
 6794        buffer_id: BufferId,
 6795        completions: Rc<RefCell<Box<[Completion]>>>,
 6796        completion_index: usize,
 6797        client: AnyProtoClient,
 6798    ) -> Result<()> {
 6799        let lsp_completion = {
 6800            let completion = &completions.borrow()[completion_index];
 6801            match &completion.source {
 6802                CompletionSource::Lsp {
 6803                    lsp_completion,
 6804                    resolved,
 6805                    server_id: completion_server_id,
 6806                    ..
 6807                } => {
 6808                    anyhow::ensure!(
 6809                        server_id == *completion_server_id,
 6810                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6811                    );
 6812                    if *resolved {
 6813                        return Ok(());
 6814                    }
 6815                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6816                }
 6817                CompletionSource::Custom
 6818                | CompletionSource::Dap { .. }
 6819                | CompletionSource::BufferWord { .. } => {
 6820                    return Ok(());
 6821                }
 6822            }
 6823        };
 6824        let request = proto::ResolveCompletionDocumentation {
 6825            project_id,
 6826            language_server_id: server_id.0 as u64,
 6827            lsp_completion,
 6828            buffer_id: buffer_id.into(),
 6829        };
 6830
 6831        let response = client
 6832            .request(request)
 6833            .await
 6834            .context("completion documentation resolve proto request")?;
 6835        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6836
 6837        let documentation = if response.documentation.is_empty() {
 6838            CompletionDocumentation::Undocumented
 6839        } else if response.documentation_is_markdown {
 6840            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6841        } else if response.documentation.lines().count() <= 1 {
 6842            CompletionDocumentation::SingleLine(response.documentation.into())
 6843        } else {
 6844            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6845        };
 6846
 6847        let mut completions = completions.borrow_mut();
 6848        let completion = &mut completions[completion_index];
 6849        completion.documentation = Some(documentation);
 6850        if let CompletionSource::Lsp {
 6851            insert_range,
 6852            lsp_completion,
 6853            resolved,
 6854            server_id: completion_server_id,
 6855            lsp_defaults: _,
 6856        } = &mut completion.source
 6857        {
 6858            let completion_insert_range = response
 6859                .old_insert_start
 6860                .and_then(deserialize_anchor)
 6861                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6862            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6863
 6864            if *resolved {
 6865                return Ok(());
 6866            }
 6867            anyhow::ensure!(
 6868                server_id == *completion_server_id,
 6869                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6870            );
 6871            **lsp_completion = resolved_lsp_completion;
 6872            *resolved = true;
 6873        }
 6874
 6875        let replace_range = response
 6876            .old_replace_start
 6877            .and_then(deserialize_anchor)
 6878            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6879        if let Some((old_replace_start, old_replace_end)) = replace_range
 6880            && !response.new_text.is_empty()
 6881        {
 6882            completion.new_text = response.new_text;
 6883            completion.replace_range = old_replace_start..old_replace_end;
 6884        }
 6885
 6886        Ok(())
 6887    }
 6888
 6889    pub fn apply_additional_edits_for_completion(
 6890        &self,
 6891        buffer_handle: Entity<Buffer>,
 6892        completions: Rc<RefCell<Box<[Completion]>>>,
 6893        completion_index: usize,
 6894        push_to_history: bool,
 6895        all_commit_ranges: Vec<Range<language::Anchor>>,
 6896        cx: &mut Context<Self>,
 6897    ) -> Task<Result<Option<Transaction>>> {
 6898        if let Some((client, project_id)) = self.upstream_client() {
 6899            let buffer = buffer_handle.read(cx);
 6900            let buffer_id = buffer.remote_id();
 6901            cx.spawn(async move |_, cx| {
 6902                let request = {
 6903                    let completion = completions.borrow()[completion_index].clone();
 6904                    proto::ApplyCompletionAdditionalEdits {
 6905                        project_id,
 6906                        buffer_id: buffer_id.into(),
 6907                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6908                            replace_range: completion.replace_range,
 6909                            new_text: completion.new_text,
 6910                            source: completion.source,
 6911                        })),
 6912                        all_commit_ranges: all_commit_ranges
 6913                            .iter()
 6914                            .cloned()
 6915                            .map(language::proto::serialize_anchor_range)
 6916                            .collect(),
 6917                    }
 6918                };
 6919
 6920                let Some(transaction) = client.request(request).await?.transaction else {
 6921                    return Ok(None);
 6922                };
 6923
 6924                let transaction = language::proto::deserialize_transaction(transaction)?;
 6925                buffer_handle
 6926                    .update(cx, |buffer, _| {
 6927                        buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6928                    })
 6929                    .await?;
 6930                if push_to_history {
 6931                    buffer_handle.update(cx, |buffer, _| {
 6932                        buffer.push_transaction(transaction.clone(), Instant::now());
 6933                        buffer.finalize_last_transaction();
 6934                    });
 6935                }
 6936                Ok(Some(transaction))
 6937            })
 6938        } else {
 6939            let request_timeout = ProjectSettings::get_global(cx)
 6940                .global_lsp_settings
 6941                .get_request_timeout();
 6942
 6943            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6944                let completion = &completions.borrow()[completion_index];
 6945                let server_id = completion.source.server_id()?;
 6946                Some(
 6947                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6948                        .1
 6949                        .clone(),
 6950                )
 6951            }) else {
 6952                return Task::ready(Ok(None));
 6953            };
 6954
 6955            cx.spawn(async move |this, cx| {
 6956                Self::resolve_completion_local(
 6957                    server.clone(),
 6958                    completions.clone(),
 6959                    completion_index,
 6960                    request_timeout,
 6961                )
 6962                .await
 6963                .context("resolving completion")?;
 6964                let completion = completions.borrow()[completion_index].clone();
 6965                let additional_text_edits = completion
 6966                    .source
 6967                    .lsp_completion(true)
 6968                    .as_ref()
 6969                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6970                if let Some(edits) = additional_text_edits {
 6971                    let edits = this
 6972                        .update(cx, |this, cx| {
 6973                            this.as_local_mut().unwrap().edits_from_lsp(
 6974                                &buffer_handle,
 6975                                edits,
 6976                                server.server_id(),
 6977                                None,
 6978                                cx,
 6979                            )
 6980                        })?
 6981                        .await?;
 6982
 6983                    buffer_handle.update(cx, |buffer, cx| {
 6984                        buffer.finalize_last_transaction();
 6985                        buffer.start_transaction();
 6986
 6987                        for (range, text) in edits {
 6988                            let primary = &completion.replace_range;
 6989
 6990                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6991                            // and the primary completion is just an insertion (empty range), then this is likely
 6992                            // an auto-import scenario and should not be considered overlapping
 6993                            // https://github.com/zed-industries/zed/issues/26136
 6994                            let is_file_start_auto_import = {
 6995                                let snapshot = buffer.snapshot();
 6996                                let primary_start_point = primary.start.to_point(&snapshot);
 6997                                let range_start_point = range.start.to_point(&snapshot);
 6998
 6999                                let result = primary_start_point.row == 0
 7000                                    && primary_start_point.column == 0
 7001                                    && range_start_point.row == 0
 7002                                    && range_start_point.column == 0;
 7003
 7004                                result
 7005                            };
 7006
 7007                            let has_overlap = if is_file_start_auto_import {
 7008                                false
 7009                            } else {
 7010                                all_commit_ranges.iter().any(|commit_range| {
 7011                                    let start_within =
 7012                                        commit_range.start.cmp(&range.start, buffer).is_le()
 7013                                            && commit_range.end.cmp(&range.start, buffer).is_ge();
 7014                                    let end_within =
 7015                                        range.start.cmp(&commit_range.end, buffer).is_le()
 7016                                            && range.end.cmp(&commit_range.end, buffer).is_ge();
 7017                                    start_within || end_within
 7018                                })
 7019                            };
 7020
 7021                            //Skip additional edits which overlap with the primary completion edit
 7022                            //https://github.com/zed-industries/zed/pull/1871
 7023                            if !has_overlap {
 7024                                buffer.edit([(range, text)], None, cx);
 7025                            }
 7026                        }
 7027
 7028                        let transaction = if buffer.end_transaction(cx).is_some() {
 7029                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 7030                            if !push_to_history {
 7031                                buffer.forget_transaction(transaction.id);
 7032                            }
 7033                            Some(transaction)
 7034                        } else {
 7035                            None
 7036                        };
 7037                        Ok(transaction)
 7038                    })
 7039                } else {
 7040                    Ok(None)
 7041                }
 7042            })
 7043        }
 7044    }
 7045
 7046    pub fn pull_diagnostics(
 7047        &mut self,
 7048        buffer: Entity<Buffer>,
 7049        cx: &mut Context<Self>,
 7050    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 7051        let buffer_id = buffer.read(cx).remote_id();
 7052
 7053        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7054            let mut suitable_capabilities = None;
 7055            // Are we capable for proto request?
 7056            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 7057                &buffer,
 7058                |capabilities| {
 7059                    if let Some(caps) = &capabilities.diagnostic_provider {
 7060                        suitable_capabilities = Some(caps.clone());
 7061                        true
 7062                    } else {
 7063                        false
 7064                    }
 7065                },
 7066                cx,
 7067            );
 7068            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 7069            let Some(dynamic_caps) = suitable_capabilities else {
 7070                return Task::ready(Ok(None));
 7071            };
 7072            assert!(any_server_has_diagnostics_provider);
 7073
 7074            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7075            let request = GetDocumentDiagnostics {
 7076                previous_result_id: None,
 7077                identifier,
 7078                registration_id: None,
 7079            };
 7080            let request_timeout = ProjectSettings::get_global(cx)
 7081                .global_lsp_settings
 7082                .get_request_timeout();
 7083            let request_task = client.request_lsp(
 7084                upstream_project_id,
 7085                None,
 7086                request_timeout,
 7087                cx.background_executor().clone(),
 7088                request.to_proto(upstream_project_id, buffer.read(cx)),
 7089            );
 7090            cx.background_spawn(async move {
 7091                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 7092                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 7093                // Do not attempt to further process the dummy responses here.
 7094                let _response = request_task.await?;
 7095                Ok(None)
 7096            })
 7097        } else {
 7098            let servers = buffer.update(cx, |buffer, cx| {
 7099                self.running_language_servers_for_local_buffer(buffer, cx)
 7100                    .map(|(_, server)| server.clone())
 7101                    .collect::<Vec<_>>()
 7102            });
 7103
 7104            let pull_diagnostics = servers
 7105                .into_iter()
 7106                .flat_map(|server| {
 7107                    let result = maybe!({
 7108                        let local = self.as_local()?;
 7109                        let server_id = server.server_id();
 7110                        let providers_with_identifiers = local
 7111                            .language_server_dynamic_registrations
 7112                            .get(&server_id)
 7113                            .into_iter()
 7114                            .flat_map(|registrations| registrations.diagnostics.clone())
 7115                            .collect::<Vec<_>>();
 7116                        Some(
 7117                            providers_with_identifiers
 7118                                .into_iter()
 7119                                .map(|(registration_id, dynamic_caps)| {
 7120                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 7121                                    let registration_id = registration_id.map(SharedString::from);
 7122                                    let result_id = self.result_id_for_buffer_pull(
 7123                                        server_id,
 7124                                        buffer_id,
 7125                                        &registration_id,
 7126                                        cx,
 7127                                    );
 7128                                    self.request_lsp(
 7129                                        buffer.clone(),
 7130                                        LanguageServerToQuery::Other(server_id),
 7131                                        GetDocumentDiagnostics {
 7132                                            previous_result_id: result_id,
 7133                                            registration_id,
 7134                                            identifier,
 7135                                        },
 7136                                        cx,
 7137                                    )
 7138                                })
 7139                                .collect::<Vec<_>>(),
 7140                        )
 7141                    });
 7142
 7143                    result.unwrap_or_default()
 7144                })
 7145                .collect::<Vec<_>>();
 7146
 7147            cx.background_spawn(async move {
 7148                let mut responses = Vec::new();
 7149                for diagnostics in join_all(pull_diagnostics).await {
 7150                    responses.extend(diagnostics?);
 7151                }
 7152                Ok(Some(responses))
 7153            })
 7154        }
 7155    }
 7156
 7157    pub fn applicable_inlay_chunks(
 7158        &mut self,
 7159        buffer: &Entity<Buffer>,
 7160        ranges: &[Range<text::Anchor>],
 7161        cx: &mut Context<Self>,
 7162    ) -> Vec<Range<BufferRow>> {
 7163        let buffer_snapshot = buffer.read(cx).snapshot();
 7164        let ranges = ranges
 7165            .iter()
 7166            .map(|range| range.to_point(&buffer_snapshot))
 7167            .collect::<Vec<_>>();
 7168
 7169        self.latest_lsp_data(buffer, cx)
 7170            .inlay_hints
 7171            .applicable_chunks(ranges.as_slice())
 7172            .map(|chunk| chunk.row_range())
 7173            .collect()
 7174    }
 7175
 7176    pub fn invalidate_inlay_hints<'a>(
 7177        &'a mut self,
 7178        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7179    ) {
 7180        for buffer_id in for_buffers {
 7181            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7182                lsp_data.inlay_hints.clear();
 7183            }
 7184        }
 7185    }
 7186
 7187    pub fn inlay_hints(
 7188        &mut self,
 7189        invalidate: InvalidationStrategy,
 7190        buffer: Entity<Buffer>,
 7191        ranges: Vec<Range<text::Anchor>>,
 7192        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7193        cx: &mut Context<Self>,
 7194    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7195        let next_hint_id = self.next_hint_id.clone();
 7196        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7197        let query_version = lsp_data.buffer_version.clone();
 7198        let mut lsp_refresh_requested = false;
 7199        let for_server = if let InvalidationStrategy::RefreshRequested {
 7200            server_id,
 7201            request_id,
 7202        } = invalidate
 7203        {
 7204            let invalidated = lsp_data
 7205                .inlay_hints
 7206                .invalidate_for_server_refresh(server_id, request_id);
 7207            lsp_refresh_requested = invalidated;
 7208            Some(server_id)
 7209        } else {
 7210            None
 7211        };
 7212        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7213        let known_chunks = known_chunks
 7214            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7215            .map(|(_, known_chunks)| known_chunks)
 7216            .unwrap_or_default();
 7217
 7218        let buffer_snapshot = buffer.read(cx).snapshot();
 7219        let ranges = ranges
 7220            .iter()
 7221            .map(|range| range.to_point(&buffer_snapshot))
 7222            .collect::<Vec<_>>();
 7223
 7224        let mut hint_fetch_tasks = Vec::new();
 7225        let mut cached_inlay_hints = None;
 7226        let mut ranges_to_query = None;
 7227        let applicable_chunks = existing_inlay_hints
 7228            .applicable_chunks(ranges.as_slice())
 7229            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7230            .collect::<Vec<_>>();
 7231        if applicable_chunks.is_empty() {
 7232            return HashMap::default();
 7233        }
 7234
 7235        for row_chunk in applicable_chunks {
 7236            match (
 7237                existing_inlay_hints
 7238                    .cached_hints(&row_chunk)
 7239                    .filter(|_| !lsp_refresh_requested)
 7240                    .cloned(),
 7241                existing_inlay_hints
 7242                    .fetched_hints(&row_chunk)
 7243                    .as_ref()
 7244                    .filter(|_| !lsp_refresh_requested)
 7245                    .cloned(),
 7246            ) {
 7247                (None, None) => {
 7248                    let chunk_range = row_chunk.anchor_range();
 7249                    ranges_to_query
 7250                        .get_or_insert_with(Vec::new)
 7251                        .push((row_chunk, chunk_range));
 7252                }
 7253                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7254                (Some(cached_hints), None) => {
 7255                    for (server_id, cached_hints) in cached_hints {
 7256                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7257                            cached_inlay_hints
 7258                                .get_or_insert_with(HashMap::default)
 7259                                .entry(row_chunk.row_range())
 7260                                .or_insert_with(HashMap::default)
 7261                                .entry(server_id)
 7262                                .or_insert_with(Vec::new)
 7263                                .extend(cached_hints);
 7264                        }
 7265                    }
 7266                }
 7267                (Some(cached_hints), Some(fetched_hints)) => {
 7268                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7269                    for (server_id, cached_hints) in cached_hints {
 7270                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7271                            cached_inlay_hints
 7272                                .get_or_insert_with(HashMap::default)
 7273                                .entry(row_chunk.row_range())
 7274                                .or_insert_with(HashMap::default)
 7275                                .entry(server_id)
 7276                                .or_insert_with(Vec::new)
 7277                                .extend(cached_hints);
 7278                        }
 7279                    }
 7280                }
 7281            }
 7282        }
 7283
 7284        if hint_fetch_tasks.is_empty()
 7285            && ranges_to_query
 7286                .as_ref()
 7287                .is_none_or(|ranges| ranges.is_empty())
 7288            && let Some(cached_inlay_hints) = cached_inlay_hints
 7289        {
 7290            cached_inlay_hints
 7291                .into_iter()
 7292                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7293                .collect()
 7294        } else {
 7295            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7296                // When a server refresh was requested, other servers' cached hints
 7297                // are unaffected by the refresh and must be included in the result.
 7298                // Otherwise apply_fetched_hints (with should_invalidate()=true)
 7299                // removes all visible hints but only adds back the requesting
 7300                // server's new hints, permanently losing other servers' hints.
 7301                let other_servers_cached: CacheInlayHints = if lsp_refresh_requested {
 7302                    lsp_data
 7303                        .inlay_hints
 7304                        .cached_hints(&chunk)
 7305                        .cloned()
 7306                        .unwrap_or_default()
 7307                } else {
 7308                    HashMap::default()
 7309                };
 7310
 7311                let next_hint_id = next_hint_id.clone();
 7312                let buffer = buffer.clone();
 7313                let query_version = query_version.clone();
 7314                let new_inlay_hints = cx
 7315                    .spawn(async move |lsp_store, cx| {
 7316                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7317                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7318                        })?;
 7319                        new_fetch_task
 7320                            .await
 7321                            .and_then(|new_hints_by_server| {
 7322                                lsp_store.update(cx, |lsp_store, cx| {
 7323                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7324                                    let update_cache = lsp_data.buffer_version == query_version;
 7325                                    if new_hints_by_server.is_empty() {
 7326                                        if update_cache {
 7327                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7328                                        }
 7329                                        other_servers_cached
 7330                                    } else {
 7331                                        let mut result = other_servers_cached;
 7332                                        for (server_id, new_hints) in new_hints_by_server {
 7333                                            let new_hints = new_hints
 7334                                                .into_iter()
 7335                                                .map(|new_hint| {
 7336                                                    (
 7337                                                        InlayId::Hint(next_hint_id.fetch_add(
 7338                                                            1,
 7339                                                            atomic::Ordering::AcqRel,
 7340                                                        )),
 7341                                                        new_hint,
 7342                                                    )
 7343                                                })
 7344                                                .collect::<Vec<_>>();
 7345                                            if update_cache {
 7346                                                lsp_data.inlay_hints.insert_new_hints(
 7347                                                    chunk,
 7348                                                    server_id,
 7349                                                    new_hints.clone(),
 7350                                                );
 7351                                            }
 7352                                            result.insert(server_id, new_hints);
 7353                                        }
 7354                                        result
 7355                                    }
 7356                                })
 7357                            })
 7358                            .map_err(Arc::new)
 7359                    })
 7360                    .shared();
 7361
 7362                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7363                *fetch_task = Some(new_inlay_hints.clone());
 7364                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7365            }
 7366
 7367            cached_inlay_hints
 7368                .unwrap_or_default()
 7369                .into_iter()
 7370                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7371                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7372                    (
 7373                        chunk.row_range(),
 7374                        cx.spawn(async move |_, _| {
 7375                            hints_fetch.await.map_err(|e| {
 7376                                if e.error_code() != ErrorCode::Internal {
 7377                                    anyhow!(e.error_code())
 7378                                } else {
 7379                                    anyhow!("{e:#}")
 7380                                }
 7381                            })
 7382                        }),
 7383                    )
 7384                }))
 7385                .collect()
 7386        }
 7387    }
 7388
 7389    fn fetch_inlay_hints(
 7390        &mut self,
 7391        for_server: Option<LanguageServerId>,
 7392        buffer: &Entity<Buffer>,
 7393        range: Range<Anchor>,
 7394        cx: &mut Context<Self>,
 7395    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7396        let request = InlayHints {
 7397            range: range.clone(),
 7398        };
 7399        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7400            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7401                return Task::ready(Ok(HashMap::default()));
 7402            }
 7403            let request_timeout = ProjectSettings::get_global(cx)
 7404                .global_lsp_settings
 7405                .get_request_timeout();
 7406            let request_task = upstream_client.request_lsp(
 7407                project_id,
 7408                for_server.map(|id| id.to_proto()),
 7409                request_timeout,
 7410                cx.background_executor().clone(),
 7411                request.to_proto(project_id, buffer.read(cx)),
 7412            );
 7413            let buffer = buffer.clone();
 7414            cx.spawn(async move |weak_lsp_store, cx| {
 7415                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7416                    return Ok(HashMap::default());
 7417                };
 7418                let Some(responses) = request_task.await? else {
 7419                    return Ok(HashMap::default());
 7420                };
 7421
 7422                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7423                    let lsp_store = lsp_store.clone();
 7424                    let buffer = buffer.clone();
 7425                    let cx = cx.clone();
 7426                    let request = request.clone();
 7427                    async move {
 7428                        (
 7429                            LanguageServerId::from_proto(response.server_id),
 7430                            request
 7431                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7432                                .await,
 7433                        )
 7434                    }
 7435                }))
 7436                .await;
 7437
 7438                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7439                let mut has_errors = false;
 7440                let inlay_hints = inlay_hints
 7441                    .into_iter()
 7442                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7443                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7444                        Err(e) => {
 7445                            has_errors = true;
 7446                            log::error!("{e:#}");
 7447                            None
 7448                        }
 7449                    })
 7450                    .map(|(server_id, mut new_hints)| {
 7451                        new_hints.retain(|hint| {
 7452                            hint.position.is_valid(&buffer_snapshot)
 7453                                && range.start.is_valid(&buffer_snapshot)
 7454                                && range.end.is_valid(&buffer_snapshot)
 7455                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7456                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7457                        });
 7458                        (server_id, new_hints)
 7459                    })
 7460                    .collect::<HashMap<_, _>>();
 7461                anyhow::ensure!(
 7462                    !has_errors || !inlay_hints.is_empty(),
 7463                    "Failed to fetch inlay hints"
 7464                );
 7465                Ok(inlay_hints)
 7466            })
 7467        } else {
 7468            let inlay_hints_task = match for_server {
 7469                Some(server_id) => {
 7470                    let server_task = self.request_lsp(
 7471                        buffer.clone(),
 7472                        LanguageServerToQuery::Other(server_id),
 7473                        request,
 7474                        cx,
 7475                    );
 7476                    cx.background_spawn(async move {
 7477                        let mut responses = Vec::new();
 7478                        match server_task.await {
 7479                            Ok(response) => responses.push((server_id, response)),
 7480                            // rust-analyzer likes to error with this when its still loading up
 7481                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7482                            Err(e) => log::error!(
 7483                                "Error handling response for inlay hints request: {e:#}"
 7484                            ),
 7485                        }
 7486                        responses
 7487                    })
 7488                }
 7489                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7490            };
 7491            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7492            cx.background_spawn(async move {
 7493                Ok(inlay_hints_task
 7494                    .await
 7495                    .into_iter()
 7496                    .map(|(server_id, mut new_hints)| {
 7497                        new_hints.retain(|hint| {
 7498                            hint.position.is_valid(&buffer_snapshot)
 7499                                && range.start.is_valid(&buffer_snapshot)
 7500                                && range.end.is_valid(&buffer_snapshot)
 7501                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7502                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7503                        });
 7504                        (server_id, new_hints)
 7505                    })
 7506                    .collect())
 7507            })
 7508        }
 7509    }
 7510
 7511    fn diagnostic_registration_exists(
 7512        &self,
 7513        server_id: LanguageServerId,
 7514        registration_id: &Option<SharedString>,
 7515    ) -> bool {
 7516        let Some(local) = self.as_local() else {
 7517            return false;
 7518        };
 7519        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7520        else {
 7521            return false;
 7522        };
 7523        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7524        registrations.diagnostics.contains_key(&registration_key)
 7525    }
 7526
 7527    pub fn pull_diagnostics_for_buffer(
 7528        &mut self,
 7529        buffer: Entity<Buffer>,
 7530        cx: &mut Context<Self>,
 7531    ) -> Task<anyhow::Result<()>> {
 7532        let diagnostics = self.pull_diagnostics(buffer, cx);
 7533        cx.spawn(async move |lsp_store, cx| {
 7534            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7535                return Ok(());
 7536            };
 7537            lsp_store.update(cx, |lsp_store, cx| {
 7538                if lsp_store.as_local().is_none() {
 7539                    return;
 7540                }
 7541
 7542                let mut unchanged_buffers = HashMap::default();
 7543                let server_diagnostics_updates = diagnostics
 7544                    .into_iter()
 7545                    .filter_map(|diagnostics_set| match diagnostics_set {
 7546                        LspPullDiagnostics::Response {
 7547                            server_id,
 7548                            uri,
 7549                            diagnostics,
 7550                            registration_id,
 7551                        } => Some((server_id, uri, diagnostics, registration_id)),
 7552                        LspPullDiagnostics::Default => None,
 7553                    })
 7554                    .filter(|(server_id, _, _, registration_id)| {
 7555                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7556                    })
 7557                    .fold(
 7558                        HashMap::default(),
 7559                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7560                            let (result_id, diagnostics) = match diagnostics {
 7561                                PulledDiagnostics::Unchanged { result_id } => {
 7562                                    unchanged_buffers
 7563                                        .entry(new_registration_id.clone())
 7564                                        .or_insert_with(HashSet::default)
 7565                                        .insert(uri.clone());
 7566                                    (Some(result_id), Vec::new())
 7567                                }
 7568                                PulledDiagnostics::Changed {
 7569                                    result_id,
 7570                                    diagnostics,
 7571                                } => (result_id, diagnostics),
 7572                            };
 7573                            let disk_based_sources = Cow::Owned(
 7574                                lsp_store
 7575                                    .language_server_adapter_for_id(server_id)
 7576                                    .as_ref()
 7577                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7578                                    .unwrap_or(&[])
 7579                                    .to_vec(),
 7580                            );
 7581                            acc.entry(server_id)
 7582                                .or_insert_with(HashMap::default)
 7583                                .entry(new_registration_id.clone())
 7584                                .or_insert_with(Vec::new)
 7585                                .push(DocumentDiagnosticsUpdate {
 7586                                    server_id,
 7587                                    diagnostics: lsp::PublishDiagnosticsParams {
 7588                                        uri,
 7589                                        diagnostics,
 7590                                        version: None,
 7591                                    },
 7592                                    result_id: result_id.map(SharedString::new),
 7593                                    disk_based_sources,
 7594                                    registration_id: new_registration_id,
 7595                                });
 7596                            acc
 7597                        },
 7598                    );
 7599
 7600                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7601                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7602                        lsp_store
 7603                            .merge_lsp_diagnostics(
 7604                                DiagnosticSourceKind::Pulled,
 7605                                diagnostic_updates,
 7606                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7607                                    DiagnosticSourceKind::Pulled => {
 7608                                        old_diagnostic.registration_id != registration_id
 7609                                            || unchanged_buffers
 7610                                                .get(&old_diagnostic.registration_id)
 7611                                                .is_some_and(|unchanged_buffers| {
 7612                                                    unchanged_buffers.contains(&document_uri)
 7613                                                })
 7614                                    }
 7615                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7616                                        true
 7617                                    }
 7618                                },
 7619                                cx,
 7620                            )
 7621                            .log_err();
 7622                    }
 7623                }
 7624            })
 7625        })
 7626    }
 7627
 7628    pub fn signature_help<T: ToPointUtf16>(
 7629        &mut self,
 7630        buffer: &Entity<Buffer>,
 7631        position: T,
 7632        cx: &mut Context<Self>,
 7633    ) -> Task<Option<Vec<SignatureHelp>>> {
 7634        let position = position.to_point_utf16(buffer.read(cx));
 7635
 7636        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7637            let request = GetSignatureHelp { position };
 7638            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7639                return Task::ready(None);
 7640            }
 7641            let request_timeout = ProjectSettings::get_global(cx)
 7642                .global_lsp_settings
 7643                .get_request_timeout();
 7644            let request_task = client.request_lsp(
 7645                upstream_project_id,
 7646                None,
 7647                request_timeout,
 7648                cx.background_executor().clone(),
 7649                request.to_proto(upstream_project_id, buffer.read(cx)),
 7650            );
 7651            let buffer = buffer.clone();
 7652            cx.spawn(async move |weak_lsp_store, cx| {
 7653                let lsp_store = weak_lsp_store.upgrade()?;
 7654                let signatures = join_all(
 7655                    request_task
 7656                        .await
 7657                        .log_err()
 7658                        .flatten()
 7659                        .map(|response| response.payload)
 7660                        .unwrap_or_default()
 7661                        .into_iter()
 7662                        .map(|response| {
 7663                            let response = GetSignatureHelp { position }.response_from_proto(
 7664                                response.response,
 7665                                lsp_store.clone(),
 7666                                buffer.clone(),
 7667                                cx.clone(),
 7668                            );
 7669                            async move { response.await.log_err().flatten() }
 7670                        }),
 7671                )
 7672                .await
 7673                .into_iter()
 7674                .flatten()
 7675                .collect();
 7676                Some(signatures)
 7677            })
 7678        } else {
 7679            let all_actions_task = self.request_multiple_lsp_locally(
 7680                buffer,
 7681                Some(position),
 7682                GetSignatureHelp { position },
 7683                cx,
 7684            );
 7685            cx.background_spawn(async move {
 7686                Some(
 7687                    all_actions_task
 7688                        .await
 7689                        .into_iter()
 7690                        .flat_map(|(_, actions)| actions)
 7691                        .collect::<Vec<_>>(),
 7692                )
 7693            })
 7694        }
 7695    }
 7696
 7697    pub fn hover(
 7698        &mut self,
 7699        buffer: &Entity<Buffer>,
 7700        position: PointUtf16,
 7701        cx: &mut Context<Self>,
 7702    ) -> Task<Option<Vec<Hover>>> {
 7703        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7704            let request = GetHover { position };
 7705            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7706                return Task::ready(None);
 7707            }
 7708            let request_timeout = ProjectSettings::get_global(cx)
 7709                .global_lsp_settings
 7710                .get_request_timeout();
 7711            let request_task = client.request_lsp(
 7712                upstream_project_id,
 7713                None,
 7714                request_timeout,
 7715                cx.background_executor().clone(),
 7716                request.to_proto(upstream_project_id, buffer.read(cx)),
 7717            );
 7718            let buffer = buffer.clone();
 7719            cx.spawn(async move |weak_lsp_store, cx| {
 7720                let lsp_store = weak_lsp_store.upgrade()?;
 7721                let hovers = join_all(
 7722                    request_task
 7723                        .await
 7724                        .log_err()
 7725                        .flatten()
 7726                        .map(|response| response.payload)
 7727                        .unwrap_or_default()
 7728                        .into_iter()
 7729                        .map(|response| {
 7730                            let response = GetHover { position }.response_from_proto(
 7731                                response.response,
 7732                                lsp_store.clone(),
 7733                                buffer.clone(),
 7734                                cx.clone(),
 7735                            );
 7736                            async move {
 7737                                response
 7738                                    .await
 7739                                    .log_err()
 7740                                    .flatten()
 7741                                    .and_then(remove_empty_hover_blocks)
 7742                            }
 7743                        }),
 7744                )
 7745                .await
 7746                .into_iter()
 7747                .flatten()
 7748                .collect();
 7749                Some(hovers)
 7750            })
 7751        } else {
 7752            let all_actions_task = self.request_multiple_lsp_locally(
 7753                buffer,
 7754                Some(position),
 7755                GetHover { position },
 7756                cx,
 7757            );
 7758            cx.background_spawn(async move {
 7759                Some(
 7760                    all_actions_task
 7761                        .await
 7762                        .into_iter()
 7763                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7764                        .collect::<Vec<Hover>>(),
 7765                )
 7766            })
 7767        }
 7768    }
 7769
 7770    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7771        let language_registry = self.languages.clone();
 7772
 7773        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7774            let request = upstream_client.request(proto::GetProjectSymbols {
 7775                project_id: *project_id,
 7776                query: query.to_string(),
 7777            });
 7778            cx.foreground_executor().spawn(async move {
 7779                let response = request.await?;
 7780                let mut symbols = Vec::new();
 7781                let core_symbols = response
 7782                    .symbols
 7783                    .into_iter()
 7784                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7785                    .collect::<Vec<_>>();
 7786                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7787                    .await;
 7788                Ok(symbols)
 7789            })
 7790        } else if let Some(local) = self.as_local() {
 7791            struct WorkspaceSymbolsResult {
 7792                server_id: LanguageServerId,
 7793                lsp_adapter: Arc<CachedLspAdapter>,
 7794                worktree: WeakEntity<Worktree>,
 7795                lsp_symbols: Vec<(String, SymbolKind, lsp::Location, Option<String>)>,
 7796            }
 7797
 7798            let mut requests = Vec::new();
 7799            let mut requested_servers = BTreeSet::new();
 7800            let request_timeout = ProjectSettings::get_global(cx)
 7801                .global_lsp_settings
 7802                .get_request_timeout();
 7803
 7804            for (seed, state) in local.language_server_ids.iter() {
 7805                let Some(worktree_handle) = self
 7806                    .worktree_store
 7807                    .read(cx)
 7808                    .worktree_for_id(seed.worktree_id, cx)
 7809                else {
 7810                    continue;
 7811                };
 7812
 7813                let worktree = worktree_handle.read(cx);
 7814                if !worktree.is_visible() {
 7815                    continue;
 7816                }
 7817
 7818                if !requested_servers.insert(state.id) {
 7819                    continue;
 7820                }
 7821
 7822                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7823                    Some(LanguageServerState::Running {
 7824                        adapter, server, ..
 7825                    }) => (adapter.clone(), server),
 7826
 7827                    _ => continue,
 7828                };
 7829
 7830                let supports_workspace_symbol_request =
 7831                    match server.capabilities().workspace_symbol_provider {
 7832                        Some(OneOf::Left(supported)) => supported,
 7833                        Some(OneOf::Right(_)) => true,
 7834                        None => false,
 7835                    };
 7836
 7837                if !supports_workspace_symbol_request {
 7838                    continue;
 7839                }
 7840
 7841                let worktree_handle = worktree_handle.clone();
 7842                let server_id = server.server_id();
 7843                requests.push(
 7844                    server
 7845                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7846                            lsp::WorkspaceSymbolParams {
 7847                                query: query.to_string(),
 7848                                ..Default::default()
 7849                            },
 7850                            request_timeout,
 7851                        )
 7852                        .map(move |response| {
 7853                            let lsp_symbols = response
 7854                                .into_response()
 7855                                .context("workspace symbols request")
 7856                                .log_err()
 7857                                .flatten()
 7858                                .map(|symbol_response| match symbol_response {
 7859                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7860                                        flat_responses
 7861                                            .into_iter()
 7862                                            .map(|lsp_symbol| {
 7863                                                (
 7864                                                    lsp_symbol.name,
 7865                                                    lsp_symbol.kind,
 7866                                                    lsp_symbol.location,
 7867                                                    lsp_symbol.container_name,
 7868                                                )
 7869                                            })
 7870                                            .collect::<Vec<_>>()
 7871                                    }
 7872                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7873                                        nested_responses
 7874                                            .into_iter()
 7875                                            .filter_map(|lsp_symbol| {
 7876                                                let location = match lsp_symbol.location {
 7877                                                    OneOf::Left(location) => location,
 7878                                                    OneOf::Right(_) => {
 7879                                                        log::error!(
 7880                                                            "Unexpected: client capabilities \
 7881                                                            forbid symbol resolutions in \
 7882                                                            workspace.symbol.resolveSupport"
 7883                                                        );
 7884                                                        return None;
 7885                                                    }
 7886                                                };
 7887                                                Some((
 7888                                                    lsp_symbol.name,
 7889                                                    lsp_symbol.kind,
 7890                                                    location,
 7891                                                    lsp_symbol.container_name,
 7892                                                ))
 7893                                            })
 7894                                            .collect::<Vec<_>>()
 7895                                    }
 7896                                })
 7897                                .unwrap_or_default();
 7898
 7899                            WorkspaceSymbolsResult {
 7900                                server_id,
 7901                                lsp_adapter,
 7902                                worktree: worktree_handle.downgrade(),
 7903                                lsp_symbols,
 7904                            }
 7905                        }),
 7906                );
 7907            }
 7908
 7909            cx.spawn(async move |this, cx| {
 7910                let responses = futures::future::join_all(requests).await;
 7911                let this = match this.upgrade() {
 7912                    Some(this) => this,
 7913                    None => return Ok(Vec::new()),
 7914                };
 7915
 7916                let mut symbols = Vec::new();
 7917                for result in responses {
 7918                    let core_symbols = this.update(cx, |this, cx| {
 7919                        result
 7920                            .lsp_symbols
 7921                            .into_iter()
 7922                            .filter_map(
 7923                                |(symbol_name, symbol_kind, symbol_location, container_name)| {
 7924                                    let abs_path = symbol_location.uri.to_file_path().ok()?;
 7925                                    let source_worktree = result.worktree.upgrade()?;
 7926                                    let source_worktree_id = source_worktree.read(cx).id();
 7927
 7928                                    let path = if let Some((tree, rel_path)) =
 7929                                        this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7930                                    {
 7931                                        let worktree_id = tree.read(cx).id();
 7932                                        SymbolLocation::InProject(ProjectPath {
 7933                                            worktree_id,
 7934                                            path: rel_path,
 7935                                        })
 7936                                    } else {
 7937                                        SymbolLocation::OutsideProject {
 7938                                            signature: this.symbol_signature(&abs_path),
 7939                                            abs_path: abs_path.into(),
 7940                                        }
 7941                                    };
 7942
 7943                                    Some(CoreSymbol {
 7944                                        source_language_server_id: result.server_id,
 7945                                        language_server_name: result.lsp_adapter.name.clone(),
 7946                                        source_worktree_id,
 7947                                        path,
 7948                                        kind: symbol_kind,
 7949                                        name: collapse_newlines(&symbol_name, ""),
 7950                                        range: range_from_lsp(symbol_location.range),
 7951                                        container_name: container_name
 7952                                            .map(|c| collapse_newlines(&c, "")),
 7953                                    })
 7954                                },
 7955                            )
 7956                            .collect::<Vec<_>>()
 7957                    });
 7958
 7959                    populate_labels_for_symbols(
 7960                        core_symbols,
 7961                        &language_registry,
 7962                        Some(result.lsp_adapter),
 7963                        &mut symbols,
 7964                    )
 7965                    .await;
 7966                }
 7967
 7968                Ok(symbols)
 7969            })
 7970        } else {
 7971            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7972        }
 7973    }
 7974
 7975    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7976        let mut summary = DiagnosticSummary::default();
 7977        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7978            summary.error_count += path_summary.error_count;
 7979            summary.warning_count += path_summary.warning_count;
 7980        }
 7981        summary
 7982    }
 7983
 7984    /// Returns the diagnostic summary for a specific project path.
 7985    pub fn diagnostic_summary_for_path(
 7986        &self,
 7987        project_path: &ProjectPath,
 7988        _: &App,
 7989    ) -> DiagnosticSummary {
 7990        if let Some(summaries) = self
 7991            .diagnostic_summaries
 7992            .get(&project_path.worktree_id)
 7993            .and_then(|map| map.get(&project_path.path))
 7994        {
 7995            let (error_count, warning_count) = summaries.iter().fold(
 7996                (0, 0),
 7997                |(error_count, warning_count), (_language_server_id, summary)| {
 7998                    (
 7999                        error_count + summary.error_count,
 8000                        warning_count + summary.warning_count,
 8001                    )
 8002                },
 8003            );
 8004
 8005            DiagnosticSummary {
 8006                error_count,
 8007                warning_count,
 8008            }
 8009        } else {
 8010            DiagnosticSummary::default()
 8011        }
 8012    }
 8013
 8014    pub fn diagnostic_summaries<'a>(
 8015        &'a self,
 8016        include_ignored: bool,
 8017        cx: &'a App,
 8018    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 8019        self.worktree_store
 8020            .read(cx)
 8021            .visible_worktrees(cx)
 8022            .filter_map(|worktree| {
 8023                let worktree = worktree.read(cx);
 8024                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 8025            })
 8026            .flat_map(move |(worktree, summaries)| {
 8027                let worktree_id = worktree.id();
 8028                summaries
 8029                    .iter()
 8030                    .filter(move |(path, _)| {
 8031                        include_ignored
 8032                            || worktree
 8033                                .entry_for_path(path.as_ref())
 8034                                .is_some_and(|entry| !entry.is_ignored)
 8035                    })
 8036                    .flat_map(move |(path, summaries)| {
 8037                        summaries.iter().map(move |(server_id, summary)| {
 8038                            (
 8039                                ProjectPath {
 8040                                    worktree_id,
 8041                                    path: path.clone(),
 8042                                },
 8043                                *server_id,
 8044                                *summary,
 8045                            )
 8046                        })
 8047                    })
 8048            })
 8049    }
 8050
 8051    pub fn on_buffer_edited(
 8052        &mut self,
 8053        buffer: Entity<Buffer>,
 8054        cx: &mut Context<Self>,
 8055    ) -> Option<()> {
 8056        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8057            Some(
 8058                self.as_local()?
 8059                    .language_servers_for_buffer(buffer, cx)
 8060                    .map(|i| i.1.clone())
 8061                    .collect(),
 8062            )
 8063        })?;
 8064
 8065        let buffer = buffer.read(cx);
 8066        let file = File::from_dyn(buffer.file())?;
 8067        let abs_path = file.as_local()?.abs_path(cx);
 8068        let uri = lsp::Uri::from_file_path(&abs_path)
 8069            .ok()
 8070            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8071            .log_err()?;
 8072        let next_snapshot = buffer.text_snapshot();
 8073        for language_server in language_servers {
 8074            let language_server = language_server.clone();
 8075
 8076            let buffer_snapshots = self
 8077                .as_local_mut()?
 8078                .buffer_snapshots
 8079                .get_mut(&buffer.remote_id())
 8080                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8081            let previous_snapshot = buffer_snapshots.last()?;
 8082
 8083            let build_incremental_change = || {
 8084                buffer
 8085                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8086                        previous_snapshot.snapshot.version(),
 8087                    )
 8088                    .map(|edit| {
 8089                        let edit_start = edit.new.start.0;
 8090                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8091                        let new_text = next_snapshot
 8092                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8093                            .collect();
 8094                        lsp::TextDocumentContentChangeEvent {
 8095                            range: Some(lsp::Range::new(
 8096                                point_to_lsp(edit_start),
 8097                                point_to_lsp(edit_end),
 8098                            )),
 8099                            range_length: None,
 8100                            text: new_text,
 8101                        }
 8102                    })
 8103                    .collect()
 8104            };
 8105
 8106            let document_sync_kind = language_server
 8107                .capabilities()
 8108                .text_document_sync
 8109                .as_ref()
 8110                .and_then(|sync| match sync {
 8111                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8112                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8113                });
 8114
 8115            let content_changes: Vec<_> = match document_sync_kind {
 8116                Some(lsp::TextDocumentSyncKind::FULL) => {
 8117                    vec![lsp::TextDocumentContentChangeEvent {
 8118                        range: None,
 8119                        range_length: None,
 8120                        text: next_snapshot.text(),
 8121                    }]
 8122                }
 8123                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8124                _ => {
 8125                    #[cfg(any(test, feature = "test-support"))]
 8126                    {
 8127                        build_incremental_change()
 8128                    }
 8129
 8130                    #[cfg(not(any(test, feature = "test-support")))]
 8131                    {
 8132                        continue;
 8133                    }
 8134                }
 8135            };
 8136
 8137            let next_version = previous_snapshot.version + 1;
 8138            buffer_snapshots.push(LspBufferSnapshot {
 8139                version: next_version,
 8140                snapshot: next_snapshot.clone(),
 8141            });
 8142
 8143            language_server
 8144                .notify::<lsp::notification::DidChangeTextDocument>(
 8145                    lsp::DidChangeTextDocumentParams {
 8146                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8147                            uri.clone(),
 8148                            next_version,
 8149                        ),
 8150                        content_changes,
 8151                    },
 8152                )
 8153                .ok();
 8154            self.pull_workspace_diagnostics(language_server.server_id());
 8155        }
 8156
 8157        None
 8158    }
 8159
 8160    pub fn on_buffer_saved(
 8161        &mut self,
 8162        buffer: Entity<Buffer>,
 8163        cx: &mut Context<Self>,
 8164    ) -> Option<()> {
 8165        let file = File::from_dyn(buffer.read(cx).file())?;
 8166        let worktree_id = file.worktree_id(cx);
 8167        let abs_path = file.as_local()?.abs_path(cx);
 8168        let text_document = lsp::TextDocumentIdentifier {
 8169            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8170        };
 8171        let local = self.as_local()?;
 8172
 8173        for server in local.language_servers_for_worktree(worktree_id) {
 8174            if let Some(include_text) = include_text(server.as_ref()) {
 8175                let text = if include_text {
 8176                    Some(buffer.read(cx).text())
 8177                } else {
 8178                    None
 8179                };
 8180                server
 8181                    .notify::<lsp::notification::DidSaveTextDocument>(
 8182                        lsp::DidSaveTextDocumentParams {
 8183                            text_document: text_document.clone(),
 8184                            text,
 8185                        },
 8186                    )
 8187                    .ok();
 8188            }
 8189        }
 8190
 8191        let language_servers = buffer.update(cx, |buffer, cx| {
 8192            local.language_server_ids_for_buffer(buffer, cx)
 8193        });
 8194        for language_server_id in language_servers {
 8195            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8196        }
 8197
 8198        None
 8199    }
 8200
 8201    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8202        maybe!(async move {
 8203            let mut refreshed_servers = HashSet::default();
 8204            let servers = lsp_store
 8205                .update(cx, |lsp_store, cx| {
 8206                    let local = lsp_store.as_local()?;
 8207
 8208                    let servers = local
 8209                        .language_server_ids
 8210                        .iter()
 8211                        .filter_map(|(seed, state)| {
 8212                            let worktree = lsp_store
 8213                                .worktree_store
 8214                                .read(cx)
 8215                                .worktree_for_id(seed.worktree_id, cx);
 8216                            let delegate: Arc<dyn LspAdapterDelegate> =
 8217                                worktree.map(|worktree| {
 8218                                    LocalLspAdapterDelegate::new(
 8219                                        local.languages.clone(),
 8220                                        &local.environment,
 8221                                        cx.weak_entity(),
 8222                                        &worktree,
 8223                                        local.http_client.clone(),
 8224                                        local.fs.clone(),
 8225                                        cx,
 8226                                    )
 8227                                })?;
 8228                            let server_id = state.id;
 8229
 8230                            let states = local.language_servers.get(&server_id)?;
 8231
 8232                            match states {
 8233                                LanguageServerState::Starting { .. } => None,
 8234                                LanguageServerState::Running {
 8235                                    adapter, server, ..
 8236                                } => {
 8237                                    let adapter = adapter.clone();
 8238                                    let server = server.clone();
 8239                                    refreshed_servers.insert(server.name());
 8240                                    let toolchain = seed.toolchain.clone();
 8241                                    Some(cx.spawn(async move |_, cx| {
 8242                                        let settings =
 8243                                            LocalLspStore::workspace_configuration_for_adapter(
 8244                                                adapter.adapter.clone(),
 8245                                                &delegate,
 8246                                                toolchain,
 8247                                                None,
 8248                                                cx,
 8249                                            )
 8250                                            .await
 8251                                            .ok()?;
 8252                                        server
 8253                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8254                                                lsp::DidChangeConfigurationParams { settings },
 8255                                            )
 8256                                            .ok()?;
 8257                                        Some(())
 8258                                    }))
 8259                                }
 8260                            }
 8261                        })
 8262                        .collect::<Vec<_>>();
 8263
 8264                    Some(servers)
 8265                })
 8266                .ok()
 8267                .flatten()?;
 8268
 8269            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8270            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8271            // to stop and unregister its language server wrapper.
 8272            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8273            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8274            let _: Vec<Option<()>> = join_all(servers).await;
 8275
 8276            Some(())
 8277        })
 8278        .await;
 8279    }
 8280
 8281    fn maintain_workspace_config(
 8282        external_refresh_requests: watch::Receiver<()>,
 8283        cx: &mut Context<Self>,
 8284    ) -> Task<Result<()>> {
 8285        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8286        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8287
 8288        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8289            *settings_changed_tx.borrow_mut() = ();
 8290        });
 8291
 8292        let mut joint_future =
 8293            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8294        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8295        // - 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).
 8296        // - 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.
 8297        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8298        // - 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,
 8299        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8300        cx.spawn(async move |this, cx| {
 8301            while let Some(()) = joint_future.next().await {
 8302                this.update(cx, |this, cx| {
 8303                    this.refresh_server_tree(cx);
 8304                })
 8305                .ok();
 8306
 8307                Self::refresh_workspace_configurations(&this, cx).await;
 8308            }
 8309
 8310            drop(settings_observation);
 8311            anyhow::Ok(())
 8312        })
 8313    }
 8314
 8315    pub fn running_language_servers_for_local_buffer<'a>(
 8316        &'a self,
 8317        buffer: &Buffer,
 8318        cx: &mut App,
 8319    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8320        let local = self.as_local();
 8321        let language_server_ids = local
 8322            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8323            .unwrap_or_default();
 8324
 8325        language_server_ids
 8326            .into_iter()
 8327            .filter_map(
 8328                move |server_id| match local?.language_servers.get(&server_id)? {
 8329                    LanguageServerState::Running {
 8330                        adapter, server, ..
 8331                    } => Some((adapter, server)),
 8332                    _ => None,
 8333                },
 8334            )
 8335    }
 8336
 8337    pub fn language_servers_for_local_buffer(
 8338        &self,
 8339        buffer: &Buffer,
 8340        cx: &mut App,
 8341    ) -> Vec<LanguageServerId> {
 8342        let local = self.as_local();
 8343        local
 8344            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8345            .unwrap_or_default()
 8346    }
 8347
 8348    pub fn language_server_for_local_buffer<'a>(
 8349        &'a self,
 8350        buffer: &'a Buffer,
 8351        server_id: LanguageServerId,
 8352        cx: &'a mut App,
 8353    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8354        self.as_local()?
 8355            .language_servers_for_buffer(buffer, cx)
 8356            .find(|(_, s)| s.server_id() == server_id)
 8357    }
 8358
 8359    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8360        self.diagnostic_summaries.remove(&id_to_remove);
 8361        if let Some(local) = self.as_local_mut() {
 8362            let to_remove = local.remove_worktree(id_to_remove, cx);
 8363            for server in to_remove {
 8364                self.language_server_statuses.remove(&server);
 8365            }
 8366        }
 8367    }
 8368
 8369    fn invalidate_diagnostic_summaries_for_removed_entries(
 8370        &mut self,
 8371        worktree_id: WorktreeId,
 8372        changes: &UpdatedEntriesSet,
 8373        cx: &mut Context<Self>,
 8374    ) {
 8375        let Some(summaries_for_tree) = self.diagnostic_summaries.get_mut(&worktree_id) else {
 8376            return;
 8377        };
 8378
 8379        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
 8380        let mut cleared_server_ids: HashSet<LanguageServerId> = HashSet::default();
 8381        let downstream = self.downstream_client.clone();
 8382
 8383        for (path, _, _) in changes
 8384            .iter()
 8385            .filter(|(_, _, change)| *change == PathChange::Removed)
 8386        {
 8387            if let Some(summaries_by_server_id) = summaries_for_tree.remove(path) {
 8388                for (server_id, _) in &summaries_by_server_id {
 8389                    cleared_server_ids.insert(*server_id);
 8390                    if let Some((client, project_id)) = &downstream {
 8391                        client
 8392                            .send(proto::UpdateDiagnosticSummary {
 8393                                project_id: *project_id,
 8394                                worktree_id: worktree_id.to_proto(),
 8395                                summary: Some(proto::DiagnosticSummary {
 8396                                    path: path.as_ref().to_proto(),
 8397                                    language_server_id: server_id.0 as u64,
 8398                                    error_count: 0,
 8399                                    warning_count: 0,
 8400                                }),
 8401                                more_summaries: Vec::new(),
 8402                            })
 8403                            .ok();
 8404                    }
 8405                }
 8406                cleared_paths.push(ProjectPath {
 8407                    worktree_id,
 8408                    path: path.clone(),
 8409                });
 8410            }
 8411        }
 8412
 8413        if !cleared_paths.is_empty() {
 8414            for server_id in cleared_server_ids {
 8415                cx.emit(LspStoreEvent::DiagnosticsUpdated {
 8416                    server_id,
 8417                    paths: cleared_paths.clone(),
 8418                });
 8419            }
 8420        }
 8421    }
 8422
 8423    pub fn shared(
 8424        &mut self,
 8425        project_id: u64,
 8426        downstream_client: AnyProtoClient,
 8427        _: &mut Context<Self>,
 8428    ) {
 8429        self.downstream_client = Some((downstream_client.clone(), project_id));
 8430
 8431        for (server_id, status) in &self.language_server_statuses {
 8432            if let Some(server) = self.language_server_for_id(*server_id) {
 8433                downstream_client
 8434                    .send(proto::StartLanguageServer {
 8435                        project_id,
 8436                        server: Some(proto::LanguageServer {
 8437                            id: server_id.to_proto(),
 8438                            name: status.name.to_string(),
 8439                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8440                        }),
 8441                        capabilities: serde_json::to_string(&server.capabilities())
 8442                            .expect("serializing server LSP capabilities"),
 8443                    })
 8444                    .log_err();
 8445            }
 8446        }
 8447    }
 8448
 8449    pub fn disconnected_from_host(&mut self) {
 8450        self.downstream_client.take();
 8451    }
 8452
 8453    pub fn disconnected_from_ssh_remote(&mut self) {
 8454        if let LspStoreMode::Remote(RemoteLspStore {
 8455            upstream_client, ..
 8456        }) = &mut self.mode
 8457        {
 8458            upstream_client.take();
 8459        }
 8460    }
 8461
 8462    pub(crate) fn set_language_server_statuses_from_proto(
 8463        &mut self,
 8464        project: WeakEntity<Project>,
 8465        language_servers: Vec<proto::LanguageServer>,
 8466        server_capabilities: Vec<String>,
 8467        cx: &mut Context<Self>,
 8468    ) {
 8469        let lsp_logs = cx
 8470            .try_global::<GlobalLogStore>()
 8471            .map(|lsp_store| lsp_store.0.clone());
 8472
 8473        self.language_server_statuses = language_servers
 8474            .into_iter()
 8475            .zip(server_capabilities)
 8476            .map(|(server, server_capabilities)| {
 8477                let server_id = LanguageServerId(server.id as usize);
 8478                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8479                    self.lsp_server_capabilities
 8480                        .insert(server_id, server_capabilities);
 8481                }
 8482
 8483                let name = LanguageServerName::from_proto(server.name);
 8484                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8485
 8486                if let Some(lsp_logs) = &lsp_logs {
 8487                    lsp_logs.update(cx, |lsp_logs, cx| {
 8488                        lsp_logs.add_language_server(
 8489                            // Only remote clients get their language servers set from proto
 8490                            LanguageServerKind::Remote {
 8491                                project: project.clone(),
 8492                            },
 8493                            server_id,
 8494                            Some(name.clone()),
 8495                            worktree,
 8496                            None,
 8497                            cx,
 8498                        );
 8499                    });
 8500                }
 8501
 8502                (
 8503                    server_id,
 8504                    LanguageServerStatus {
 8505                        name,
 8506                        server_version: None,
 8507                        server_readable_version: None,
 8508                        pending_work: Default::default(),
 8509                        has_pending_diagnostic_updates: false,
 8510                        progress_tokens: Default::default(),
 8511                        worktree,
 8512                        binary: None,
 8513                        configuration: None,
 8514                        workspace_folders: BTreeSet::new(),
 8515                        process_id: None,
 8516                    },
 8517                )
 8518            })
 8519            .collect();
 8520    }
 8521
 8522    #[cfg(feature = "test-support")]
 8523    pub fn update_diagnostic_entries(
 8524        &mut self,
 8525        server_id: LanguageServerId,
 8526        abs_path: PathBuf,
 8527        result_id: Option<SharedString>,
 8528        version: Option<i32>,
 8529        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8530        cx: &mut Context<Self>,
 8531    ) -> anyhow::Result<()> {
 8532        self.merge_diagnostic_entries(
 8533            vec![DocumentDiagnosticsUpdate {
 8534                diagnostics: DocumentDiagnostics {
 8535                    diagnostics,
 8536                    document_abs_path: abs_path,
 8537                    version,
 8538                },
 8539                result_id,
 8540                server_id,
 8541                disk_based_sources: Cow::Borrowed(&[]),
 8542                registration_id: None,
 8543            }],
 8544            |_, _, _| false,
 8545            cx,
 8546        )?;
 8547        Ok(())
 8548    }
 8549
 8550    pub fn merge_diagnostic_entries<'a>(
 8551        &mut self,
 8552        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8553        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8554        cx: &mut Context<Self>,
 8555    ) -> anyhow::Result<()> {
 8556        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8557        let mut updated_diagnostics_paths = HashMap::default();
 8558        for mut update in diagnostic_updates {
 8559            let abs_path = &update.diagnostics.document_abs_path;
 8560            let server_id = update.server_id;
 8561            let Some((worktree, relative_path)) =
 8562                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8563            else {
 8564                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8565                return Ok(());
 8566            };
 8567
 8568            let worktree_id = worktree.read(cx).id();
 8569            let project_path = ProjectPath {
 8570                worktree_id,
 8571                path: relative_path,
 8572            };
 8573
 8574            let document_uri = lsp::Uri::from_file_path(abs_path)
 8575                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8576            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8577                let snapshot = buffer_handle.read(cx).snapshot();
 8578                let buffer = buffer_handle.read(cx);
 8579                let reused_diagnostics = buffer
 8580                    .buffer_diagnostics(Some(server_id))
 8581                    .iter()
 8582                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8583                    .map(|v| {
 8584                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8585                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8586                        DiagnosticEntry {
 8587                            range: start..end,
 8588                            diagnostic: v.diagnostic.clone(),
 8589                        }
 8590                    })
 8591                    .collect::<Vec<_>>();
 8592
 8593                self.as_local_mut()
 8594                    .context("cannot merge diagnostics on a remote LspStore")?
 8595                    .update_buffer_diagnostics(
 8596                        &buffer_handle,
 8597                        server_id,
 8598                        Some(update.registration_id),
 8599                        update.result_id,
 8600                        update.diagnostics.version,
 8601                        update.diagnostics.diagnostics.clone(),
 8602                        reused_diagnostics.clone(),
 8603                        cx,
 8604                    )?;
 8605
 8606                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8607            } else if let Some(local) = self.as_local() {
 8608                let reused_diagnostics = local
 8609                    .diagnostics
 8610                    .get(&worktree_id)
 8611                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8612                    .and_then(|diagnostics_by_server_id| {
 8613                        diagnostics_by_server_id
 8614                            .binary_search_by_key(&server_id, |e| e.0)
 8615                            .ok()
 8616                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8617                    })
 8618                    .into_iter()
 8619                    .flatten()
 8620                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8621
 8622                update
 8623                    .diagnostics
 8624                    .diagnostics
 8625                    .extend(reused_diagnostics.cloned());
 8626            }
 8627
 8628            let updated = worktree.update(cx, |worktree, cx| {
 8629                self.update_worktree_diagnostics(
 8630                    worktree.id(),
 8631                    server_id,
 8632                    project_path.path.clone(),
 8633                    update.diagnostics.diagnostics,
 8634                    cx,
 8635                )
 8636            })?;
 8637            match updated {
 8638                ControlFlow::Continue(new_summary) => {
 8639                    if let Some((project_id, new_summary)) = new_summary {
 8640                        match &mut diagnostics_summary {
 8641                            Some(diagnostics_summary) => {
 8642                                diagnostics_summary
 8643                                    .more_summaries
 8644                                    .push(proto::DiagnosticSummary {
 8645                                        path: project_path.path.as_ref().to_proto(),
 8646                                        language_server_id: server_id.0 as u64,
 8647                                        error_count: new_summary.error_count,
 8648                                        warning_count: new_summary.warning_count,
 8649                                    })
 8650                            }
 8651                            None => {
 8652                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8653                                    project_id,
 8654                                    worktree_id: worktree_id.to_proto(),
 8655                                    summary: Some(proto::DiagnosticSummary {
 8656                                        path: project_path.path.as_ref().to_proto(),
 8657                                        language_server_id: server_id.0 as u64,
 8658                                        error_count: new_summary.error_count,
 8659                                        warning_count: new_summary.warning_count,
 8660                                    }),
 8661                                    more_summaries: Vec::new(),
 8662                                })
 8663                            }
 8664                        }
 8665                    }
 8666                    updated_diagnostics_paths
 8667                        .entry(server_id)
 8668                        .or_insert_with(Vec::new)
 8669                        .push(project_path);
 8670                }
 8671                ControlFlow::Break(()) => {}
 8672            }
 8673        }
 8674
 8675        if let Some((diagnostics_summary, (downstream_client, _))) =
 8676            diagnostics_summary.zip(self.downstream_client.as_ref())
 8677        {
 8678            downstream_client.send(diagnostics_summary).log_err();
 8679        }
 8680        for (server_id, paths) in updated_diagnostics_paths {
 8681            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8682        }
 8683        Ok(())
 8684    }
 8685
 8686    fn update_worktree_diagnostics(
 8687        &mut self,
 8688        worktree_id: WorktreeId,
 8689        server_id: LanguageServerId,
 8690        path_in_worktree: Arc<RelPath>,
 8691        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8692        _: &mut Context<Worktree>,
 8693    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8694        let local = match &mut self.mode {
 8695            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8696            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8697        };
 8698
 8699        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8700        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8701        let summaries_by_server_id = summaries_for_tree
 8702            .entry(path_in_worktree.clone())
 8703            .or_default();
 8704
 8705        let old_summary = summaries_by_server_id
 8706            .remove(&server_id)
 8707            .unwrap_or_default();
 8708
 8709        let new_summary = DiagnosticSummary::new(&diagnostics);
 8710        if diagnostics.is_empty() {
 8711            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8712            {
 8713                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8714                    diagnostics_by_server_id.remove(ix);
 8715                }
 8716                if diagnostics_by_server_id.is_empty() {
 8717                    diagnostics_for_tree.remove(&path_in_worktree);
 8718                }
 8719            }
 8720        } else {
 8721            summaries_by_server_id.insert(server_id, new_summary);
 8722            let diagnostics_by_server_id = diagnostics_for_tree
 8723                .entry(path_in_worktree.clone())
 8724                .or_default();
 8725            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8726                Ok(ix) => {
 8727                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8728                }
 8729                Err(ix) => {
 8730                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8731                }
 8732            }
 8733        }
 8734
 8735        if !old_summary.is_empty() || !new_summary.is_empty() {
 8736            if let Some((_, project_id)) = &self.downstream_client {
 8737                Ok(ControlFlow::Continue(Some((
 8738                    *project_id,
 8739                    proto::DiagnosticSummary {
 8740                        path: path_in_worktree.to_proto(),
 8741                        language_server_id: server_id.0 as u64,
 8742                        error_count: new_summary.error_count as u32,
 8743                        warning_count: new_summary.warning_count as u32,
 8744                    },
 8745                ))))
 8746            } else {
 8747                Ok(ControlFlow::Continue(None))
 8748            }
 8749        } else {
 8750            Ok(ControlFlow::Break(()))
 8751        }
 8752    }
 8753
 8754    pub fn open_buffer_for_symbol(
 8755        &mut self,
 8756        symbol: &Symbol,
 8757        cx: &mut Context<Self>,
 8758    ) -> Task<Result<Entity<Buffer>>> {
 8759        if let Some((client, project_id)) = self.upstream_client() {
 8760            let request = client.request(proto::OpenBufferForSymbol {
 8761                project_id,
 8762                symbol: Some(Self::serialize_symbol(symbol)),
 8763            });
 8764            cx.spawn(async move |this, cx| {
 8765                let response = request.await?;
 8766                let buffer_id = BufferId::new(response.buffer_id)?;
 8767                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8768                    .await
 8769            })
 8770        } else if let Some(local) = self.as_local() {
 8771            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8772                seed.worktree_id == symbol.source_worktree_id
 8773                    && state.id == symbol.source_language_server_id
 8774                    && symbol.language_server_name == seed.name
 8775            });
 8776            if !is_valid {
 8777                return Task::ready(Err(anyhow!(
 8778                    "language server for worktree and language not found"
 8779                )));
 8780            };
 8781
 8782            let symbol_abs_path = match &symbol.path {
 8783                SymbolLocation::InProject(project_path) => self
 8784                    .worktree_store
 8785                    .read(cx)
 8786                    .absolutize(&project_path, cx)
 8787                    .context("no such worktree"),
 8788                SymbolLocation::OutsideProject {
 8789                    abs_path,
 8790                    signature: _,
 8791                } => Ok(abs_path.to_path_buf()),
 8792            };
 8793            let symbol_abs_path = match symbol_abs_path {
 8794                Ok(abs_path) => abs_path,
 8795                Err(err) => return Task::ready(Err(err)),
 8796            };
 8797            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8798                uri
 8799            } else {
 8800                return Task::ready(Err(anyhow!("invalid symbol path")));
 8801            };
 8802
 8803            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8804        } else {
 8805            Task::ready(Err(anyhow!("no upstream client or local store")))
 8806        }
 8807    }
 8808
 8809    pub(crate) fn open_local_buffer_via_lsp(
 8810        &mut self,
 8811        abs_path: lsp::Uri,
 8812        language_server_id: LanguageServerId,
 8813        cx: &mut Context<Self>,
 8814    ) -> Task<Result<Entity<Buffer>>> {
 8815        let path_style = self.worktree_store.read(cx).path_style();
 8816        cx.spawn(async move |lsp_store, cx| {
 8817            // Escape percent-encoded string.
 8818            let current_scheme = abs_path.scheme().to_owned();
 8819            // Uri is immutable, so we can't modify the scheme
 8820
 8821            let abs_path = abs_path
 8822                .to_file_path_ext(path_style)
 8823                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8824            let p = abs_path.clone();
 8825            let yarn_worktree = lsp_store
 8826                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8827                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8828                        cx.spawn(async move |this, cx| {
 8829                            let t = this
 8830                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8831                                .ok()?;
 8832                            t.await
 8833                        })
 8834                    }),
 8835                    None => Task::ready(None),
 8836                })?
 8837                .await;
 8838            let (worktree_root_target, known_relative_path) =
 8839                if let Some((zip_root, relative_path)) = yarn_worktree {
 8840                    (zip_root, Some(relative_path))
 8841                } else {
 8842                    (Arc::<Path>::from(abs_path.as_path()), None)
 8843                };
 8844            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8845                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8846                    worktree_store.find_worktree(&worktree_root_target, cx)
 8847                })
 8848            })?;
 8849            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8850                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8851                (result.0, relative_path, None)
 8852            } else {
 8853                let worktree = lsp_store
 8854                    .update(cx, |lsp_store, cx| {
 8855                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8856                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8857                        })
 8858                    })?
 8859                    .await?;
 8860                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8861                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8862                    lsp_store
 8863                        .update(cx, |lsp_store, cx| {
 8864                            if let Some(local) = lsp_store.as_local_mut() {
 8865                                local.register_language_server_for_invisible_worktree(
 8866                                    &worktree,
 8867                                    language_server_id,
 8868                                    cx,
 8869                                )
 8870                            }
 8871                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8872                                Some(status) => status.worktree,
 8873                                None => None,
 8874                            }
 8875                        })
 8876                        .ok()
 8877                        .flatten()
 8878                        .zip(Some(worktree_root.clone()))
 8879                } else {
 8880                    None
 8881                };
 8882                let relative_path = if let Some(known_path) = known_relative_path {
 8883                    known_path
 8884                } else {
 8885                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8886                        .into_arc()
 8887                };
 8888                (worktree, relative_path, source_ws)
 8889            };
 8890            let project_path = ProjectPath {
 8891                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8892                path: relative_path,
 8893            };
 8894            let buffer = lsp_store
 8895                .update(cx, |lsp_store, cx| {
 8896                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8897                        buffer_store.open_buffer(project_path, cx)
 8898                    })
 8899                })?
 8900                .await?;
 8901            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8902            if let Some((source_ws, worktree_root)) = source_ws {
 8903                buffer.update(cx, |buffer, cx| {
 8904                    let settings = WorktreeSettings::get(
 8905                        Some(
 8906                            (&ProjectPath {
 8907                                worktree_id: source_ws,
 8908                                path: Arc::from(RelPath::empty()),
 8909                            })
 8910                                .into(),
 8911                        ),
 8912                        cx,
 8913                    );
 8914                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8915                    if is_read_only {
 8916                        buffer.set_capability(Capability::ReadOnly, cx);
 8917                    }
 8918                });
 8919            }
 8920            Ok(buffer)
 8921        })
 8922    }
 8923
 8924    fn local_lsp_servers_for_buffer(
 8925        &self,
 8926        buffer: &Entity<Buffer>,
 8927        cx: &mut Context<Self>,
 8928    ) -> Vec<LanguageServerId> {
 8929        let Some(local) = self.as_local() else {
 8930            return Vec::new();
 8931        };
 8932
 8933        let snapshot = buffer.read(cx).snapshot();
 8934
 8935        buffer.update(cx, |buffer, cx| {
 8936            local
 8937                .language_servers_for_buffer(buffer, cx)
 8938                .map(|(_, server)| server.server_id())
 8939                .filter(|server_id| {
 8940                    self.as_local().is_none_or(|local| {
 8941                        local
 8942                            .buffers_opened_in_servers
 8943                            .get(&snapshot.remote_id())
 8944                            .is_some_and(|servers| servers.contains(server_id))
 8945                    })
 8946                })
 8947                .collect()
 8948        })
 8949    }
 8950
 8951    fn request_multiple_lsp_locally<P, R>(
 8952        &mut self,
 8953        buffer: &Entity<Buffer>,
 8954        position: Option<P>,
 8955        request: R,
 8956        cx: &mut Context<Self>,
 8957    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8958    where
 8959        P: ToOffset,
 8960        R: LspCommand + Clone,
 8961        <R::LspRequest as lsp::request::Request>::Result: Send,
 8962        <R::LspRequest as lsp::request::Request>::Params: Send,
 8963    {
 8964        let Some(local) = self.as_local() else {
 8965            return Task::ready(Vec::new());
 8966        };
 8967
 8968        let snapshot = buffer.read(cx).snapshot();
 8969        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8970
 8971        let server_ids = buffer.update(cx, |buffer, cx| {
 8972            local
 8973                .language_servers_for_buffer(buffer, cx)
 8974                .filter(|(adapter, _)| {
 8975                    scope
 8976                        .as_ref()
 8977                        .map(|scope| scope.language_allowed(&adapter.name))
 8978                        .unwrap_or(true)
 8979                })
 8980                .map(|(_, server)| server.server_id())
 8981                .filter(|server_id| {
 8982                    self.as_local().is_none_or(|local| {
 8983                        local
 8984                            .buffers_opened_in_servers
 8985                            .get(&snapshot.remote_id())
 8986                            .is_some_and(|servers| servers.contains(server_id))
 8987                    })
 8988                })
 8989                .collect::<Vec<_>>()
 8990        });
 8991
 8992        let mut response_results = server_ids
 8993            .into_iter()
 8994            .map(|server_id| {
 8995                let task = self.request_lsp(
 8996                    buffer.clone(),
 8997                    LanguageServerToQuery::Other(server_id),
 8998                    request.clone(),
 8999                    cx,
 9000                );
 9001                async move { (server_id, task.await) }
 9002            })
 9003            .collect::<FuturesUnordered<_>>();
 9004
 9005        cx.background_spawn(async move {
 9006            let mut responses = Vec::with_capacity(response_results.len());
 9007            while let Some((server_id, response_result)) = response_results.next().await {
 9008                match response_result {
 9009                    Ok(response) => responses.push((server_id, response)),
 9010                    // rust-analyzer likes to error with this when its still loading up
 9011                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 9012                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 9013                }
 9014            }
 9015            responses
 9016        })
 9017    }
 9018
 9019    async fn handle_lsp_get_completions(
 9020        this: Entity<Self>,
 9021        envelope: TypedEnvelope<proto::GetCompletions>,
 9022        mut cx: AsyncApp,
 9023    ) -> Result<proto::GetCompletionsResponse> {
 9024        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9025
 9026        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 9027        let buffer_handle = this.update(&mut cx, |this, cx| {
 9028            this.buffer_store.read(cx).get_existing(buffer_id)
 9029        })?;
 9030        let request = GetCompletions::from_proto(
 9031            envelope.payload,
 9032            this.clone(),
 9033            buffer_handle.clone(),
 9034            cx.clone(),
 9035        )
 9036        .await?;
 9037
 9038        let server_to_query = match request.server_id {
 9039            Some(server_id) => LanguageServerToQuery::Other(server_id),
 9040            None => LanguageServerToQuery::FirstCapable,
 9041        };
 9042
 9043        let response = this
 9044            .update(&mut cx, |this, cx| {
 9045                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 9046            })
 9047            .await?;
 9048        this.update(&mut cx, |this, cx| {
 9049            Ok(GetCompletions::response_to_proto(
 9050                response,
 9051                this,
 9052                sender_id,
 9053                &buffer_handle.read(cx).version(),
 9054                cx,
 9055            ))
 9056        })
 9057    }
 9058
 9059    async fn handle_lsp_command<T: LspCommand>(
 9060        this: Entity<Self>,
 9061        envelope: TypedEnvelope<T::ProtoRequest>,
 9062        mut cx: AsyncApp,
 9063    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 9064    where
 9065        <T::LspRequest as lsp::request::Request>::Params: Send,
 9066        <T::LspRequest as lsp::request::Request>::Result: Send,
 9067    {
 9068        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9069        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 9070        let buffer_handle = this.update(&mut cx, |this, cx| {
 9071            this.buffer_store.read(cx).get_existing(buffer_id)
 9072        })?;
 9073        let request = T::from_proto(
 9074            envelope.payload,
 9075            this.clone(),
 9076            buffer_handle.clone(),
 9077            cx.clone(),
 9078        )
 9079        .await?;
 9080        let response = this
 9081            .update(&mut cx, |this, cx| {
 9082                this.request_lsp(
 9083                    buffer_handle.clone(),
 9084                    LanguageServerToQuery::FirstCapable,
 9085                    request,
 9086                    cx,
 9087                )
 9088            })
 9089            .await?;
 9090        this.update(&mut cx, |this, cx| {
 9091            Ok(T::response_to_proto(
 9092                response,
 9093                this,
 9094                sender_id,
 9095                &buffer_handle.read(cx).version(),
 9096                cx,
 9097            ))
 9098        })
 9099    }
 9100
 9101    async fn handle_lsp_query(
 9102        lsp_store: Entity<Self>,
 9103        envelope: TypedEnvelope<proto::LspQuery>,
 9104        mut cx: AsyncApp,
 9105    ) -> Result<proto::Ack> {
 9106        use proto::lsp_query::Request;
 9107        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9108        let lsp_query = envelope.payload;
 9109        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9110        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9111        match lsp_query.request.context("invalid LSP query request")? {
 9112            Request::GetReferences(get_references) => {
 9113                let position = get_references.position.clone().and_then(deserialize_anchor);
 9114                Self::query_lsp_locally::<GetReferences>(
 9115                    lsp_store,
 9116                    server_id,
 9117                    sender_id,
 9118                    lsp_request_id,
 9119                    get_references,
 9120                    position,
 9121                    &mut cx,
 9122                )
 9123                .await?;
 9124            }
 9125            Request::GetDocumentColor(get_document_color) => {
 9126                Self::query_lsp_locally::<GetDocumentColor>(
 9127                    lsp_store,
 9128                    server_id,
 9129                    sender_id,
 9130                    lsp_request_id,
 9131                    get_document_color,
 9132                    None,
 9133                    &mut cx,
 9134                )
 9135                .await?;
 9136            }
 9137            Request::GetFoldingRanges(get_folding_ranges) => {
 9138                Self::query_lsp_locally::<GetFoldingRanges>(
 9139                    lsp_store,
 9140                    server_id,
 9141                    sender_id,
 9142                    lsp_request_id,
 9143                    get_folding_ranges,
 9144                    None,
 9145                    &mut cx,
 9146                )
 9147                .await?;
 9148            }
 9149            Request::GetDocumentSymbols(get_document_symbols) => {
 9150                Self::query_lsp_locally::<GetDocumentSymbols>(
 9151                    lsp_store,
 9152                    server_id,
 9153                    sender_id,
 9154                    lsp_request_id,
 9155                    get_document_symbols,
 9156                    None,
 9157                    &mut cx,
 9158                )
 9159                .await?;
 9160            }
 9161            Request::GetHover(get_hover) => {
 9162                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9163                Self::query_lsp_locally::<GetHover>(
 9164                    lsp_store,
 9165                    server_id,
 9166                    sender_id,
 9167                    lsp_request_id,
 9168                    get_hover,
 9169                    position,
 9170                    &mut cx,
 9171                )
 9172                .await?;
 9173            }
 9174            Request::GetCodeActions(get_code_actions) => {
 9175                Self::query_lsp_locally::<GetCodeActions>(
 9176                    lsp_store,
 9177                    server_id,
 9178                    sender_id,
 9179                    lsp_request_id,
 9180                    get_code_actions,
 9181                    None,
 9182                    &mut cx,
 9183                )
 9184                .await?;
 9185            }
 9186            Request::GetSignatureHelp(get_signature_help) => {
 9187                let position = get_signature_help
 9188                    .position
 9189                    .clone()
 9190                    .and_then(deserialize_anchor);
 9191                Self::query_lsp_locally::<GetSignatureHelp>(
 9192                    lsp_store,
 9193                    server_id,
 9194                    sender_id,
 9195                    lsp_request_id,
 9196                    get_signature_help,
 9197                    position,
 9198                    &mut cx,
 9199                )
 9200                .await?;
 9201            }
 9202            Request::GetCodeLens(get_code_lens) => {
 9203                Self::query_lsp_locally::<GetCodeLens>(
 9204                    lsp_store,
 9205                    server_id,
 9206                    sender_id,
 9207                    lsp_request_id,
 9208                    get_code_lens,
 9209                    None,
 9210                    &mut cx,
 9211                )
 9212                .await?;
 9213            }
 9214            Request::GetDefinition(get_definition) => {
 9215                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9216                Self::query_lsp_locally::<GetDefinitions>(
 9217                    lsp_store,
 9218                    server_id,
 9219                    sender_id,
 9220                    lsp_request_id,
 9221                    get_definition,
 9222                    position,
 9223                    &mut cx,
 9224                )
 9225                .await?;
 9226            }
 9227            Request::GetDeclaration(get_declaration) => {
 9228                let position = get_declaration
 9229                    .position
 9230                    .clone()
 9231                    .and_then(deserialize_anchor);
 9232                Self::query_lsp_locally::<GetDeclarations>(
 9233                    lsp_store,
 9234                    server_id,
 9235                    sender_id,
 9236                    lsp_request_id,
 9237                    get_declaration,
 9238                    position,
 9239                    &mut cx,
 9240                )
 9241                .await?;
 9242            }
 9243            Request::GetTypeDefinition(get_type_definition) => {
 9244                let position = get_type_definition
 9245                    .position
 9246                    .clone()
 9247                    .and_then(deserialize_anchor);
 9248                Self::query_lsp_locally::<GetTypeDefinitions>(
 9249                    lsp_store,
 9250                    server_id,
 9251                    sender_id,
 9252                    lsp_request_id,
 9253                    get_type_definition,
 9254                    position,
 9255                    &mut cx,
 9256                )
 9257                .await?;
 9258            }
 9259            Request::GetImplementation(get_implementation) => {
 9260                let position = get_implementation
 9261                    .position
 9262                    .clone()
 9263                    .and_then(deserialize_anchor);
 9264                Self::query_lsp_locally::<GetImplementations>(
 9265                    lsp_store,
 9266                    server_id,
 9267                    sender_id,
 9268                    lsp_request_id,
 9269                    get_implementation,
 9270                    position,
 9271                    &mut cx,
 9272                )
 9273                .await?;
 9274            }
 9275            Request::InlayHints(inlay_hints) => {
 9276                let query_start = inlay_hints
 9277                    .start
 9278                    .clone()
 9279                    .and_then(deserialize_anchor)
 9280                    .context("invalid inlay hints range start")?;
 9281                let query_end = inlay_hints
 9282                    .end
 9283                    .clone()
 9284                    .and_then(deserialize_anchor)
 9285                    .context("invalid inlay hints range end")?;
 9286                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9287                    &lsp_store,
 9288                    server_id,
 9289                    lsp_request_id,
 9290                    &inlay_hints,
 9291                    query_start..query_end,
 9292                    &mut cx,
 9293                )
 9294                .await
 9295                .context("preparing inlay hints request")?;
 9296                Self::query_lsp_locally::<InlayHints>(
 9297                    lsp_store,
 9298                    server_id,
 9299                    sender_id,
 9300                    lsp_request_id,
 9301                    inlay_hints,
 9302                    None,
 9303                    &mut cx,
 9304                )
 9305                .await
 9306                .context("querying for inlay hints")?
 9307            }
 9308            //////////////////////////////
 9309            // Below are LSP queries that need to fetch more data,
 9310            // hence cannot just proxy the request to language server with `query_lsp_locally`.
 9311            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9312                let (_, buffer) = Self::wait_for_buffer_version::<GetDocumentDiagnostics>(
 9313                    &lsp_store,
 9314                    &get_document_diagnostics,
 9315                    &mut cx,
 9316                )
 9317                .await?;
 9318                lsp_store.update(&mut cx, |lsp_store, cx| {
 9319                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9320                    let key = LspKey {
 9321                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9322                        server_queried: server_id,
 9323                    };
 9324                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9325                    ) {
 9326                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9327                            lsp_requests.clear();
 9328                        };
 9329                    }
 9330
 9331                    lsp_data.lsp_requests.entry(key).or_default().insert(
 9332                        lsp_request_id,
 9333                        cx.spawn(async move |lsp_store, cx| {
 9334                            let diagnostics_pull = lsp_store
 9335                                .update(cx, |lsp_store, cx| {
 9336                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9337                                })
 9338                                .ok();
 9339                            if let Some(diagnostics_pull) = diagnostics_pull {
 9340                                match diagnostics_pull.await {
 9341                                    Ok(()) => {}
 9342                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9343                                };
 9344                            }
 9345                        }),
 9346                    );
 9347                });
 9348            }
 9349            Request::SemanticTokens(semantic_tokens) => {
 9350                let (buffer_version, buffer) = Self::wait_for_buffer_version::<SemanticTokensFull>(
 9351                    &lsp_store,
 9352                    &semantic_tokens,
 9353                    &mut cx,
 9354                )
 9355                .await?;
 9356                let for_server = semantic_tokens.for_server.map(LanguageServerId::from_proto);
 9357                lsp_store.update(&mut cx, |lsp_store, cx| {
 9358                    if let Some((client, project_id)) = lsp_store.downstream_client.clone() {
 9359                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9360                        let key = LspKey {
 9361                            request_type: TypeId::of::<SemanticTokensFull>(),
 9362                            server_queried: server_id,
 9363                        };
 9364                        if <SemanticTokensFull as LspCommand>::ProtoRequest::stop_previous_requests() {
 9365                            if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9366                                lsp_requests.clear();
 9367                            };
 9368                        }
 9369
 9370                        lsp_data.lsp_requests.entry(key).or_default().insert(
 9371                            lsp_request_id,
 9372                            cx.spawn(async move |lsp_store, cx| {
 9373                                let tokens_fetch = lsp_store
 9374                                    .update(cx, |lsp_store, cx| {
 9375                                        lsp_store
 9376                                            .fetch_semantic_tokens_for_buffer(&buffer, for_server, cx)
 9377                                    })
 9378                                    .ok();
 9379                                if let Some(tokens_fetch) = tokens_fetch {
 9380                                    let new_tokens = tokens_fetch.await;
 9381                                    if let Some(new_tokens) = new_tokens {
 9382                                        lsp_store
 9383                                            .update(cx, |lsp_store, cx| {
 9384                                                let response = new_tokens
 9385                                                    .into_iter()
 9386                                                    .map(|(server_id, response)| {
 9387                                                        (
 9388                                                            server_id.to_proto(),
 9389                                                            SemanticTokensFull::response_to_proto(
 9390                                                                response,
 9391                                                                lsp_store,
 9392                                                                sender_id,
 9393                                                                &buffer_version,
 9394                                                                cx,
 9395                                                            ),
 9396                                                        )
 9397                                                    })
 9398                                                    .collect::<HashMap<_, _>>();
 9399                                                match client.send_lsp_response::<<SemanticTokensFull as LspCommand>::ProtoRequest>(
 9400                                                    project_id,
 9401                                                    lsp_request_id,
 9402                                                    response,
 9403                                                ) {
 9404                                                    Ok(()) => {}
 9405                                                    Err(e) => {
 9406                                                        log::error!(
 9407                                                            "Failed to send semantic tokens LSP response: {e:#}",
 9408                                                        )
 9409                                                    }
 9410                                                }
 9411                                            })
 9412                                            .ok();
 9413                                    }
 9414                                }
 9415                            }),
 9416                        );
 9417                    }
 9418                });
 9419            }
 9420        }
 9421        Ok(proto::Ack {})
 9422    }
 9423
 9424    async fn handle_lsp_query_response(
 9425        lsp_store: Entity<Self>,
 9426        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9427        cx: AsyncApp,
 9428    ) -> Result<()> {
 9429        lsp_store.read_with(&cx, |lsp_store, _| {
 9430            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9431                upstream_client.handle_lsp_response(envelope.clone());
 9432            }
 9433        });
 9434        Ok(())
 9435    }
 9436
 9437    async fn handle_apply_code_action(
 9438        this: Entity<Self>,
 9439        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9440        mut cx: AsyncApp,
 9441    ) -> Result<proto::ApplyCodeActionResponse> {
 9442        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9443        let action =
 9444            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9445        let apply_code_action = this.update(&mut cx, |this, cx| {
 9446            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9447            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9448            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9449        })?;
 9450
 9451        let project_transaction = apply_code_action.await?;
 9452        let project_transaction = this.update(&mut cx, |this, cx| {
 9453            this.buffer_store.update(cx, |buffer_store, cx| {
 9454                buffer_store.serialize_project_transaction_for_peer(
 9455                    project_transaction,
 9456                    sender_id,
 9457                    cx,
 9458                )
 9459            })
 9460        });
 9461        Ok(proto::ApplyCodeActionResponse {
 9462            transaction: Some(project_transaction),
 9463        })
 9464    }
 9465
 9466    async fn handle_register_buffer_with_language_servers(
 9467        this: Entity<Self>,
 9468        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9469        mut cx: AsyncApp,
 9470    ) -> Result<proto::Ack> {
 9471        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9472        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9473        this.update(&mut cx, |this, cx| {
 9474            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9475                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9476                    project_id: upstream_project_id,
 9477                    buffer_id: buffer_id.to_proto(),
 9478                    only_servers: envelope.payload.only_servers,
 9479                });
 9480            }
 9481
 9482            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9483                anyhow::bail!("buffer is not open");
 9484            };
 9485
 9486            let handle = this.register_buffer_with_language_servers(
 9487                &buffer,
 9488                envelope
 9489                    .payload
 9490                    .only_servers
 9491                    .into_iter()
 9492                    .filter_map(|selector| {
 9493                        Some(match selector.selector? {
 9494                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9495                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9496                            }
 9497                            proto::language_server_selector::Selector::Name(name) => {
 9498                                LanguageServerSelector::Name(LanguageServerName(
 9499                                    SharedString::from(name),
 9500                                ))
 9501                            }
 9502                        })
 9503                    })
 9504                    .collect(),
 9505                false,
 9506                cx,
 9507            );
 9508            // Pull diagnostics for the buffer even if it was already registered.
 9509            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9510            // but it's unclear if we need it.
 9511            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9512                .detach();
 9513            this.buffer_store().update(cx, |buffer_store, _| {
 9514                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9515            });
 9516
 9517            Ok(())
 9518        })?;
 9519        Ok(proto::Ack {})
 9520    }
 9521
 9522    async fn handle_rename_project_entry(
 9523        this: Entity<Self>,
 9524        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9525        mut cx: AsyncApp,
 9526    ) -> Result<proto::ProjectEntryResponse> {
 9527        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9528        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9529        let new_path =
 9530            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9531
 9532        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9533            .update(&mut cx, |this, cx| {
 9534                let (worktree, entry) = this
 9535                    .worktree_store
 9536                    .read(cx)
 9537                    .worktree_and_entry_for_id(entry_id, cx)?;
 9538                let new_worktree = this
 9539                    .worktree_store
 9540                    .read(cx)
 9541                    .worktree_for_id(new_worktree_id, cx)?;
 9542                Some((
 9543                    this.worktree_store.clone(),
 9544                    worktree,
 9545                    new_worktree,
 9546                    entry.clone(),
 9547                ))
 9548            })
 9549            .context("worktree not found")?;
 9550        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9551            (worktree.absolutize(&old_entry.path), worktree.id())
 9552        });
 9553        let new_abs_path =
 9554            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9555
 9556        let _transaction = Self::will_rename_entry(
 9557            this.downgrade(),
 9558            old_worktree_id,
 9559            &old_abs_path,
 9560            &new_abs_path,
 9561            old_entry.is_dir(),
 9562            cx.clone(),
 9563        )
 9564        .await;
 9565        let response = WorktreeStore::handle_rename_project_entry(
 9566            worktree_store,
 9567            envelope.payload,
 9568            cx.clone(),
 9569        )
 9570        .await;
 9571        this.read_with(&cx, |this, _| {
 9572            this.did_rename_entry(
 9573                old_worktree_id,
 9574                &old_abs_path,
 9575                &new_abs_path,
 9576                old_entry.is_dir(),
 9577            );
 9578        });
 9579        response
 9580    }
 9581
 9582    async fn handle_update_diagnostic_summary(
 9583        this: Entity<Self>,
 9584        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9585        mut cx: AsyncApp,
 9586    ) -> Result<()> {
 9587        this.update(&mut cx, |lsp_store, cx| {
 9588            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9589            let mut updated_diagnostics_paths = HashMap::default();
 9590            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9591            for message_summary in envelope
 9592                .payload
 9593                .summary
 9594                .into_iter()
 9595                .chain(envelope.payload.more_summaries)
 9596            {
 9597                let project_path = ProjectPath {
 9598                    worktree_id,
 9599                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9600                };
 9601                let path = project_path.path.clone();
 9602                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9603                let summary = DiagnosticSummary {
 9604                    error_count: message_summary.error_count as usize,
 9605                    warning_count: message_summary.warning_count as usize,
 9606                };
 9607
 9608                if summary.is_empty() {
 9609                    if let Some(worktree_summaries) =
 9610                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9611                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9612                    {
 9613                        summaries.remove(&server_id);
 9614                        if summaries.is_empty() {
 9615                            worktree_summaries.remove(&path);
 9616                        }
 9617                    }
 9618                } else {
 9619                    lsp_store
 9620                        .diagnostic_summaries
 9621                        .entry(worktree_id)
 9622                        .or_default()
 9623                        .entry(path)
 9624                        .or_default()
 9625                        .insert(server_id, summary);
 9626                }
 9627
 9628                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9629                    match &mut diagnostics_summary {
 9630                        Some(diagnostics_summary) => {
 9631                            diagnostics_summary
 9632                                .more_summaries
 9633                                .push(proto::DiagnosticSummary {
 9634                                    path: project_path.path.as_ref().to_proto(),
 9635                                    language_server_id: server_id.0 as u64,
 9636                                    error_count: summary.error_count as u32,
 9637                                    warning_count: summary.warning_count as u32,
 9638                                })
 9639                        }
 9640                        None => {
 9641                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9642                                project_id: *project_id,
 9643                                worktree_id: worktree_id.to_proto(),
 9644                                summary: Some(proto::DiagnosticSummary {
 9645                                    path: project_path.path.as_ref().to_proto(),
 9646                                    language_server_id: server_id.0 as u64,
 9647                                    error_count: summary.error_count as u32,
 9648                                    warning_count: summary.warning_count as u32,
 9649                                }),
 9650                                more_summaries: Vec::new(),
 9651                            })
 9652                        }
 9653                    }
 9654                }
 9655                updated_diagnostics_paths
 9656                    .entry(server_id)
 9657                    .or_insert_with(Vec::new)
 9658                    .push(project_path);
 9659            }
 9660
 9661            if let Some((diagnostics_summary, (downstream_client, _))) =
 9662                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9663            {
 9664                downstream_client.send(diagnostics_summary).log_err();
 9665            }
 9666            for (server_id, paths) in updated_diagnostics_paths {
 9667                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9668            }
 9669            Ok(())
 9670        })
 9671    }
 9672
 9673    async fn handle_start_language_server(
 9674        lsp_store: Entity<Self>,
 9675        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9676        mut cx: AsyncApp,
 9677    ) -> Result<()> {
 9678        let server = envelope.payload.server.context("invalid server")?;
 9679        let server_capabilities =
 9680            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9681                .with_context(|| {
 9682                    format!(
 9683                        "incorrect server capabilities {}",
 9684                        envelope.payload.capabilities
 9685                    )
 9686                })?;
 9687        lsp_store.update(&mut cx, |lsp_store, cx| {
 9688            let server_id = LanguageServerId(server.id as usize);
 9689            let server_name = LanguageServerName::from_proto(server.name.clone());
 9690            lsp_store
 9691                .lsp_server_capabilities
 9692                .insert(server_id, server_capabilities);
 9693            lsp_store.language_server_statuses.insert(
 9694                server_id,
 9695                LanguageServerStatus {
 9696                    name: server_name.clone(),
 9697                    server_version: None,
 9698                    server_readable_version: None,
 9699                    pending_work: Default::default(),
 9700                    has_pending_diagnostic_updates: false,
 9701                    progress_tokens: Default::default(),
 9702                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9703                    binary: None,
 9704                    configuration: None,
 9705                    workspace_folders: BTreeSet::new(),
 9706                    process_id: None,
 9707                },
 9708            );
 9709            cx.emit(LspStoreEvent::LanguageServerAdded(
 9710                server_id,
 9711                server_name,
 9712                server.worktree_id.map(WorktreeId::from_proto),
 9713            ));
 9714            cx.notify();
 9715        });
 9716        Ok(())
 9717    }
 9718
 9719    async fn handle_update_language_server(
 9720        lsp_store: Entity<Self>,
 9721        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9722        mut cx: AsyncApp,
 9723    ) -> Result<()> {
 9724        lsp_store.update(&mut cx, |lsp_store, cx| {
 9725            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9726
 9727            match envelope.payload.variant.context("invalid variant")? {
 9728                proto::update_language_server::Variant::WorkStart(payload) => {
 9729                    lsp_store.on_lsp_work_start(
 9730                        language_server_id,
 9731                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9732                            .context("invalid progress token value")?,
 9733                        LanguageServerProgress {
 9734                            title: payload.title,
 9735                            is_disk_based_diagnostics_progress: false,
 9736                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9737                            message: payload.message,
 9738                            percentage: payload.percentage.map(|p| p as usize),
 9739                            last_update_at: cx.background_executor().now(),
 9740                        },
 9741                        cx,
 9742                    );
 9743                }
 9744                proto::update_language_server::Variant::WorkProgress(payload) => {
 9745                    lsp_store.on_lsp_work_progress(
 9746                        language_server_id,
 9747                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9748                            .context("invalid progress token value")?,
 9749                        LanguageServerProgress {
 9750                            title: None,
 9751                            is_disk_based_diagnostics_progress: false,
 9752                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9753                            message: payload.message,
 9754                            percentage: payload.percentage.map(|p| p as usize),
 9755                            last_update_at: cx.background_executor().now(),
 9756                        },
 9757                        cx,
 9758                    );
 9759                }
 9760
 9761                proto::update_language_server::Variant::WorkEnd(payload) => {
 9762                    lsp_store.on_lsp_work_end(
 9763                        language_server_id,
 9764                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9765                            .context("invalid progress token value")?,
 9766                        cx,
 9767                    );
 9768                }
 9769
 9770                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9771                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9772                }
 9773
 9774                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9775                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9776                }
 9777
 9778                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9779                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9780                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9781                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9782                        language_server_id,
 9783                        name: envelope
 9784                            .payload
 9785                            .server_name
 9786                            .map(SharedString::new)
 9787                            .map(LanguageServerName),
 9788                        message: non_lsp,
 9789                    });
 9790                }
 9791            }
 9792
 9793            Ok(())
 9794        })
 9795    }
 9796
 9797    async fn handle_language_server_log(
 9798        this: Entity<Self>,
 9799        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9800        mut cx: AsyncApp,
 9801    ) -> Result<()> {
 9802        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9803        let log_type = envelope
 9804            .payload
 9805            .log_type
 9806            .map(LanguageServerLogType::from_proto)
 9807            .context("invalid language server log type")?;
 9808
 9809        let message = envelope.payload.message;
 9810
 9811        this.update(&mut cx, |_, cx| {
 9812            cx.emit(LspStoreEvent::LanguageServerLog(
 9813                language_server_id,
 9814                log_type,
 9815                message,
 9816            ));
 9817        });
 9818        Ok(())
 9819    }
 9820
 9821    async fn handle_lsp_ext_cancel_flycheck(
 9822        lsp_store: Entity<Self>,
 9823        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9824        cx: AsyncApp,
 9825    ) -> Result<proto::Ack> {
 9826        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9827        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9828            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9829                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9830            } else {
 9831                None
 9832            }
 9833        });
 9834        if let Some(task) = task {
 9835            task.context("handling lsp ext cancel flycheck")?;
 9836        }
 9837
 9838        Ok(proto::Ack {})
 9839    }
 9840
 9841    async fn handle_lsp_ext_run_flycheck(
 9842        lsp_store: Entity<Self>,
 9843        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9844        mut cx: AsyncApp,
 9845    ) -> Result<proto::Ack> {
 9846        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9847        lsp_store.update(&mut cx, |lsp_store, cx| {
 9848            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9849                let text_document = if envelope.payload.current_file_only {
 9850                    let buffer_id = envelope
 9851                        .payload
 9852                        .buffer_id
 9853                        .map(|id| BufferId::new(id))
 9854                        .transpose()?;
 9855                    buffer_id
 9856                        .and_then(|buffer_id| {
 9857                            lsp_store
 9858                                .buffer_store()
 9859                                .read(cx)
 9860                                .get(buffer_id)
 9861                                .and_then(|buffer| {
 9862                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9863                                })
 9864                                .map(|path| make_text_document_identifier(&path))
 9865                        })
 9866                        .transpose()?
 9867                } else {
 9868                    None
 9869                };
 9870                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9871                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9872                )?;
 9873            }
 9874            anyhow::Ok(())
 9875        })?;
 9876
 9877        Ok(proto::Ack {})
 9878    }
 9879
 9880    async fn handle_lsp_ext_clear_flycheck(
 9881        lsp_store: Entity<Self>,
 9882        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9883        cx: AsyncApp,
 9884    ) -> Result<proto::Ack> {
 9885        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9886        lsp_store.read_with(&cx, |lsp_store, _| {
 9887            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9888                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9889            } else {
 9890                None
 9891            }
 9892        });
 9893
 9894        Ok(proto::Ack {})
 9895    }
 9896
 9897    pub fn disk_based_diagnostics_started(
 9898        &mut self,
 9899        language_server_id: LanguageServerId,
 9900        cx: &mut Context<Self>,
 9901    ) {
 9902        if let Some(language_server_status) =
 9903            self.language_server_statuses.get_mut(&language_server_id)
 9904        {
 9905            language_server_status.has_pending_diagnostic_updates = true;
 9906        }
 9907
 9908        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9909        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9910            language_server_id,
 9911            name: self
 9912                .language_server_adapter_for_id(language_server_id)
 9913                .map(|adapter| adapter.name()),
 9914            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9915                Default::default(),
 9916            ),
 9917        })
 9918    }
 9919
 9920    pub fn disk_based_diagnostics_finished(
 9921        &mut self,
 9922        language_server_id: LanguageServerId,
 9923        cx: &mut Context<Self>,
 9924    ) {
 9925        if let Some(language_server_status) =
 9926            self.language_server_statuses.get_mut(&language_server_id)
 9927        {
 9928            language_server_status.has_pending_diagnostic_updates = false;
 9929        }
 9930
 9931        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9932        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9933            language_server_id,
 9934            name: self
 9935                .language_server_adapter_for_id(language_server_id)
 9936                .map(|adapter| adapter.name()),
 9937            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9938                Default::default(),
 9939            ),
 9940        })
 9941    }
 9942
 9943    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9944    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9945    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9946    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9947    // the language server might take some time to publish diagnostics.
 9948    fn simulate_disk_based_diagnostics_events_if_needed(
 9949        &mut self,
 9950        language_server_id: LanguageServerId,
 9951        cx: &mut Context<Self>,
 9952    ) {
 9953        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9954
 9955        let Some(LanguageServerState::Running {
 9956            simulate_disk_based_diagnostics_completion,
 9957            adapter,
 9958            ..
 9959        }) = self
 9960            .as_local_mut()
 9961            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9962        else {
 9963            return;
 9964        };
 9965
 9966        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9967            return;
 9968        }
 9969
 9970        let prev_task =
 9971            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9972                cx.background_executor()
 9973                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9974                    .await;
 9975
 9976                this.update(cx, |this, cx| {
 9977                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9978
 9979                    if let Some(LanguageServerState::Running {
 9980                        simulate_disk_based_diagnostics_completion,
 9981                        ..
 9982                    }) = this.as_local_mut().and_then(|local_store| {
 9983                        local_store.language_servers.get_mut(&language_server_id)
 9984                    }) {
 9985                        *simulate_disk_based_diagnostics_completion = None;
 9986                    }
 9987                })
 9988                .ok();
 9989            }));
 9990
 9991        if prev_task.is_none() {
 9992            self.disk_based_diagnostics_started(language_server_id, cx);
 9993        }
 9994    }
 9995
 9996    pub fn language_server_statuses(
 9997        &self,
 9998    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9999        self.language_server_statuses
10000            .iter()
10001            .map(|(key, value)| (*key, value))
10002    }
10003
10004    pub(super) fn did_rename_entry(
10005        &self,
10006        worktree_id: WorktreeId,
10007        old_path: &Path,
10008        new_path: &Path,
10009        is_dir: bool,
10010    ) {
10011        maybe!({
10012            let local_store = self.as_local()?;
10013
10014            let old_uri = lsp::Uri::from_file_path(old_path)
10015                .ok()
10016                .map(|uri| uri.to_string())?;
10017            let new_uri = lsp::Uri::from_file_path(new_path)
10018                .ok()
10019                .map(|uri| uri.to_string())?;
10020
10021            for language_server in local_store.language_servers_for_worktree(worktree_id) {
10022                let Some(filter) = local_store
10023                    .language_server_paths_watched_for_rename
10024                    .get(&language_server.server_id())
10025                else {
10026                    continue;
10027                };
10028
10029                if filter.should_send_did_rename(&old_uri, is_dir) {
10030                    language_server
10031                        .notify::<DidRenameFiles>(RenameFilesParams {
10032                            files: vec![FileRename {
10033                                old_uri: old_uri.clone(),
10034                                new_uri: new_uri.clone(),
10035                            }],
10036                        })
10037                        .ok();
10038                }
10039            }
10040            Some(())
10041        });
10042    }
10043
10044    pub(super) fn will_rename_entry(
10045        this: WeakEntity<Self>,
10046        worktree_id: WorktreeId,
10047        old_path: &Path,
10048        new_path: &Path,
10049        is_dir: bool,
10050        cx: AsyncApp,
10051    ) -> Task<ProjectTransaction> {
10052        let old_uri = lsp::Uri::from_file_path(old_path)
10053            .ok()
10054            .map(|uri| uri.to_string());
10055        let new_uri = lsp::Uri::from_file_path(new_path)
10056            .ok()
10057            .map(|uri| uri.to_string());
10058        cx.spawn(async move |cx| {
10059            let mut tasks = vec![];
10060            this.update(cx, |this, cx| {
10061                let local_store = this.as_local()?;
10062                let old_uri = old_uri?;
10063                let new_uri = new_uri?;
10064                for language_server in local_store.language_servers_for_worktree(worktree_id) {
10065                    let Some(filter) = local_store
10066                        .language_server_paths_watched_for_rename
10067                        .get(&language_server.server_id())
10068                    else {
10069                        continue;
10070                    };
10071
10072                    if !filter.should_send_will_rename(&old_uri, is_dir) {
10073                        continue;
10074                    }
10075                    let request_timeout = ProjectSettings::get_global(cx)
10076                        .global_lsp_settings
10077                        .get_request_timeout();
10078
10079                    let apply_edit = cx.spawn({
10080                        let old_uri = old_uri.clone();
10081                        let new_uri = new_uri.clone();
10082                        let language_server = language_server.clone();
10083                        async move |this, cx| {
10084                            let edit = language_server
10085                                .request::<WillRenameFiles>(
10086                                    RenameFilesParams {
10087                                        files: vec![FileRename { old_uri, new_uri }],
10088                                    },
10089                                    request_timeout,
10090                                )
10091                                .await
10092                                .into_response()
10093                                .context("will rename files")
10094                                .log_err()
10095                                .flatten()?;
10096
10097                            LocalLspStore::deserialize_workspace_edit(
10098                                this.upgrade()?,
10099                                edit,
10100                                false,
10101                                language_server.clone(),
10102                                cx,
10103                            )
10104                            .await
10105                            .ok()
10106                        }
10107                    });
10108                    tasks.push(apply_edit);
10109                }
10110                Some(())
10111            })
10112            .ok()
10113            .flatten();
10114            let mut merged_transaction = ProjectTransaction::default();
10115            for task in tasks {
10116                // Await on tasks sequentially so that the order of application of edits is deterministic
10117                // (at least with regards to the order of registration of language servers)
10118                if let Some(transaction) = task.await {
10119                    for (buffer, buffer_transaction) in transaction.0 {
10120                        merged_transaction.0.insert(buffer, buffer_transaction);
10121                    }
10122                }
10123            }
10124            merged_transaction
10125        })
10126    }
10127
10128    fn lsp_notify_abs_paths_changed(
10129        &mut self,
10130        server_id: LanguageServerId,
10131        changes: Vec<PathEvent>,
10132    ) {
10133        maybe!({
10134            let server = self.language_server_for_id(server_id)?;
10135            let changes = changes
10136                .into_iter()
10137                .filter_map(|event| {
10138                    let typ = match event.kind? {
10139                        PathEventKind::Created => lsp::FileChangeType::CREATED,
10140                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
10141                        PathEventKind::Changed | PathEventKind::Rescan => {
10142                            lsp::FileChangeType::CHANGED
10143                        }
10144                    };
10145                    Some(lsp::FileEvent {
10146                        uri: file_path_to_lsp_url(&event.path).log_err()?,
10147                        typ,
10148                    })
10149                })
10150                .collect::<Vec<_>>();
10151            if !changes.is_empty() {
10152                server
10153                    .notify::<lsp::notification::DidChangeWatchedFiles>(
10154                        lsp::DidChangeWatchedFilesParams { changes },
10155                    )
10156                    .ok();
10157            }
10158            Some(())
10159        });
10160    }
10161
10162    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
10163        self.as_local()?.language_server_for_id(id)
10164    }
10165
10166    fn on_lsp_progress(
10167        &mut self,
10168        progress_params: lsp::ProgressParams,
10169        language_server_id: LanguageServerId,
10170        disk_based_diagnostics_progress_token: Option<String>,
10171        cx: &mut Context<Self>,
10172    ) {
10173        match progress_params.value {
10174            lsp::ProgressParamsValue::WorkDone(progress) => {
10175                self.handle_work_done_progress(
10176                    progress,
10177                    language_server_id,
10178                    disk_based_diagnostics_progress_token,
10179                    ProgressToken::from_lsp(progress_params.token),
10180                    cx,
10181                );
10182            }
10183            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10184                let registration_id = match progress_params.token {
10185                    lsp::NumberOrString::Number(_) => None,
10186                    lsp::NumberOrString::String(token) => token
10187                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10188                        .map(|(_, id)| id.to_owned()),
10189                };
10190                if let Some(LanguageServerState::Running {
10191                    workspace_diagnostics_refresh_tasks,
10192                    ..
10193                }) = self
10194                    .as_local_mut()
10195                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10196                    && let Some(workspace_diagnostics) =
10197                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10198                {
10199                    workspace_diagnostics.progress_tx.try_send(()).ok();
10200                    self.apply_workspace_diagnostic_report(
10201                        language_server_id,
10202                        report,
10203                        registration_id.map(SharedString::from),
10204                        cx,
10205                    )
10206                }
10207            }
10208        }
10209    }
10210
10211    fn handle_work_done_progress(
10212        &mut self,
10213        progress: lsp::WorkDoneProgress,
10214        language_server_id: LanguageServerId,
10215        disk_based_diagnostics_progress_token: Option<String>,
10216        token: ProgressToken,
10217        cx: &mut Context<Self>,
10218    ) {
10219        let language_server_status =
10220            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10221                status
10222            } else {
10223                return;
10224            };
10225
10226        if !language_server_status.progress_tokens.contains(&token) {
10227            return;
10228        }
10229
10230        let is_disk_based_diagnostics_progress =
10231            if let (Some(disk_based_token), ProgressToken::String(token)) =
10232                (&disk_based_diagnostics_progress_token, &token)
10233            {
10234                token.starts_with(disk_based_token)
10235            } else {
10236                false
10237            };
10238
10239        match progress {
10240            lsp::WorkDoneProgress::Begin(report) => {
10241                if is_disk_based_diagnostics_progress {
10242                    self.disk_based_diagnostics_started(language_server_id, cx);
10243                }
10244                self.on_lsp_work_start(
10245                    language_server_id,
10246                    token.clone(),
10247                    LanguageServerProgress {
10248                        title: Some(report.title),
10249                        is_disk_based_diagnostics_progress,
10250                        is_cancellable: report.cancellable.unwrap_or(false),
10251                        message: report.message.clone(),
10252                        percentage: report.percentage.map(|p| p as usize),
10253                        last_update_at: cx.background_executor().now(),
10254                    },
10255                    cx,
10256                );
10257            }
10258            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10259                language_server_id,
10260                token,
10261                LanguageServerProgress {
10262                    title: None,
10263                    is_disk_based_diagnostics_progress,
10264                    is_cancellable: report.cancellable.unwrap_or(false),
10265                    message: report.message,
10266                    percentage: report.percentage.map(|p| p as usize),
10267                    last_update_at: cx.background_executor().now(),
10268                },
10269                cx,
10270            ),
10271            lsp::WorkDoneProgress::End(_) => {
10272                language_server_status.progress_tokens.remove(&token);
10273                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10274                if is_disk_based_diagnostics_progress {
10275                    self.disk_based_diagnostics_finished(language_server_id, cx);
10276                }
10277            }
10278        }
10279    }
10280
10281    fn on_lsp_work_start(
10282        &mut self,
10283        language_server_id: LanguageServerId,
10284        token: ProgressToken,
10285        progress: LanguageServerProgress,
10286        cx: &mut Context<Self>,
10287    ) {
10288        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10289            status.pending_work.insert(token.clone(), progress.clone());
10290            cx.notify();
10291        }
10292        cx.emit(LspStoreEvent::LanguageServerUpdate {
10293            language_server_id,
10294            name: self
10295                .language_server_adapter_for_id(language_server_id)
10296                .map(|adapter| adapter.name()),
10297            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10298                token: Some(token.to_proto()),
10299                title: progress.title,
10300                message: progress.message,
10301                percentage: progress.percentage.map(|p| p as u32),
10302                is_cancellable: Some(progress.is_cancellable),
10303            }),
10304        })
10305    }
10306
10307    fn on_lsp_work_progress(
10308        &mut self,
10309        language_server_id: LanguageServerId,
10310        token: ProgressToken,
10311        progress: LanguageServerProgress,
10312        cx: &mut Context<Self>,
10313    ) {
10314        let mut did_update = false;
10315        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10316            match status.pending_work.entry(token.clone()) {
10317                btree_map::Entry::Vacant(entry) => {
10318                    entry.insert(progress.clone());
10319                    did_update = true;
10320                }
10321                btree_map::Entry::Occupied(mut entry) => {
10322                    let entry = entry.get_mut();
10323                    if (progress.last_update_at - entry.last_update_at)
10324                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10325                    {
10326                        entry.last_update_at = progress.last_update_at;
10327                        if progress.message.is_some() {
10328                            entry.message = progress.message.clone();
10329                        }
10330                        if progress.percentage.is_some() {
10331                            entry.percentage = progress.percentage;
10332                        }
10333                        if progress.is_cancellable != entry.is_cancellable {
10334                            entry.is_cancellable = progress.is_cancellable;
10335                        }
10336                        did_update = true;
10337                    }
10338                }
10339            }
10340        }
10341
10342        if did_update {
10343            cx.emit(LspStoreEvent::LanguageServerUpdate {
10344                language_server_id,
10345                name: self
10346                    .language_server_adapter_for_id(language_server_id)
10347                    .map(|adapter| adapter.name()),
10348                message: proto::update_language_server::Variant::WorkProgress(
10349                    proto::LspWorkProgress {
10350                        token: Some(token.to_proto()),
10351                        message: progress.message,
10352                        percentage: progress.percentage.map(|p| p as u32),
10353                        is_cancellable: Some(progress.is_cancellable),
10354                    },
10355                ),
10356            })
10357        }
10358    }
10359
10360    fn on_lsp_work_end(
10361        &mut self,
10362        language_server_id: LanguageServerId,
10363        token: ProgressToken,
10364        cx: &mut Context<Self>,
10365    ) {
10366        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10367            if let Some(work) = status.pending_work.remove(&token)
10368                && !work.is_disk_based_diagnostics_progress
10369            {
10370                cx.emit(LspStoreEvent::RefreshInlayHints {
10371                    server_id: language_server_id,
10372                    request_id: None,
10373                });
10374            }
10375            cx.notify();
10376        }
10377
10378        cx.emit(LspStoreEvent::LanguageServerUpdate {
10379            language_server_id,
10380            name: self
10381                .language_server_adapter_for_id(language_server_id)
10382                .map(|adapter| adapter.name()),
10383            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10384                token: Some(token.to_proto()),
10385            }),
10386        })
10387    }
10388
10389    pub async fn handle_resolve_completion_documentation(
10390        this: Entity<Self>,
10391        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10392        mut cx: AsyncApp,
10393    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10394        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10395
10396        let completion = this
10397            .read_with(&cx, |this, cx| {
10398                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10399                let server = this
10400                    .language_server_for_id(id)
10401                    .with_context(|| format!("No language server {id}"))?;
10402
10403                let request_timeout = ProjectSettings::get_global(cx)
10404                    .global_lsp_settings
10405                    .get_request_timeout();
10406
10407                anyhow::Ok(cx.background_spawn(async move {
10408                    let can_resolve = server
10409                        .capabilities()
10410                        .completion_provider
10411                        .as_ref()
10412                        .and_then(|options| options.resolve_provider)
10413                        .unwrap_or(false);
10414                    if can_resolve {
10415                        server
10416                            .request::<lsp::request::ResolveCompletionItem>(
10417                                lsp_completion,
10418                                request_timeout,
10419                            )
10420                            .await
10421                            .into_response()
10422                            .context("resolve completion item")
10423                    } else {
10424                        anyhow::Ok(lsp_completion)
10425                    }
10426                }))
10427            })?
10428            .await?;
10429
10430        let mut documentation_is_markdown = false;
10431        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10432        let documentation = match completion.documentation {
10433            Some(lsp::Documentation::String(text)) => text,
10434
10435            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10436                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10437                value
10438            }
10439
10440            _ => String::new(),
10441        };
10442
10443        // If we have a new buffer_id, that means we're talking to a new client
10444        // and want to check for new text_edits in the completion too.
10445        let mut old_replace_start = None;
10446        let mut old_replace_end = None;
10447        let mut old_insert_start = None;
10448        let mut old_insert_end = None;
10449        let mut new_text = String::default();
10450        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10451            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10452                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10453                anyhow::Ok(buffer.read(cx).snapshot())
10454            })?;
10455
10456            if let Some(text_edit) = completion.text_edit.as_ref() {
10457                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10458
10459                if let Some(mut edit) = edit {
10460                    LineEnding::normalize(&mut edit.new_text);
10461
10462                    new_text = edit.new_text;
10463                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10464                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10465                    if let Some(insert_range) = edit.insert_range {
10466                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10467                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10468                    }
10469                }
10470            }
10471        }
10472
10473        Ok(proto::ResolveCompletionDocumentationResponse {
10474            documentation,
10475            documentation_is_markdown,
10476            old_replace_start,
10477            old_replace_end,
10478            new_text,
10479            lsp_completion,
10480            old_insert_start,
10481            old_insert_end,
10482        })
10483    }
10484
10485    async fn handle_on_type_formatting(
10486        this: Entity<Self>,
10487        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10488        mut cx: AsyncApp,
10489    ) -> Result<proto::OnTypeFormattingResponse> {
10490        let on_type_formatting = this.update(&mut cx, |this, cx| {
10491            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10492            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10493            let position = envelope
10494                .payload
10495                .position
10496                .and_then(deserialize_anchor)
10497                .context("invalid position")?;
10498            anyhow::Ok(this.apply_on_type_formatting(
10499                buffer,
10500                position,
10501                envelope.payload.trigger.clone(),
10502                cx,
10503            ))
10504        })?;
10505
10506        let transaction = on_type_formatting
10507            .await?
10508            .as_ref()
10509            .map(language::proto::serialize_transaction);
10510        Ok(proto::OnTypeFormattingResponse { transaction })
10511    }
10512
10513    async fn handle_pull_workspace_diagnostics(
10514        lsp_store: Entity<Self>,
10515        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10516        mut cx: AsyncApp,
10517    ) -> Result<proto::Ack> {
10518        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10519        lsp_store.update(&mut cx, |lsp_store, _| {
10520            lsp_store.pull_workspace_diagnostics(server_id);
10521        });
10522        Ok(proto::Ack {})
10523    }
10524
10525    async fn handle_open_buffer_for_symbol(
10526        this: Entity<Self>,
10527        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10528        mut cx: AsyncApp,
10529    ) -> Result<proto::OpenBufferForSymbolResponse> {
10530        let peer_id = envelope.original_sender_id().unwrap_or_default();
10531        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10532        let symbol = Self::deserialize_symbol(symbol)?;
10533        this.read_with(&cx, |this, _| {
10534            if let SymbolLocation::OutsideProject {
10535                abs_path,
10536                signature,
10537            } = &symbol.path
10538            {
10539                let new_signature = this.symbol_signature(&abs_path);
10540                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10541            }
10542            Ok(())
10543        })?;
10544        let buffer = this
10545            .update(&mut cx, |this, cx| {
10546                this.open_buffer_for_symbol(
10547                    &Symbol {
10548                        language_server_name: symbol.language_server_name,
10549                        source_worktree_id: symbol.source_worktree_id,
10550                        source_language_server_id: symbol.source_language_server_id,
10551                        path: symbol.path,
10552                        name: symbol.name,
10553                        kind: symbol.kind,
10554                        range: symbol.range,
10555                        label: CodeLabel::default(),
10556                        container_name: symbol.container_name,
10557                    },
10558                    cx,
10559                )
10560            })
10561            .await?;
10562
10563        this.update(&mut cx, |this, cx| {
10564            let is_private = buffer
10565                .read(cx)
10566                .file()
10567                .map(|f| f.is_private())
10568                .unwrap_or_default();
10569            if is_private {
10570                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10571            } else {
10572                this.buffer_store
10573                    .update(cx, |buffer_store, cx| {
10574                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10575                    })
10576                    .detach_and_log_err(cx);
10577                let buffer_id = buffer.read(cx).remote_id().to_proto();
10578                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10579            }
10580        })
10581    }
10582
10583    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10584        let mut hasher = Sha256::new();
10585        hasher.update(abs_path.to_string_lossy().as_bytes());
10586        hasher.update(self.nonce.to_be_bytes());
10587        hasher.finalize().as_slice().try_into().unwrap()
10588    }
10589
10590    pub async fn handle_get_project_symbols(
10591        this: Entity<Self>,
10592        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10593        mut cx: AsyncApp,
10594    ) -> Result<proto::GetProjectSymbolsResponse> {
10595        let symbols = this
10596            .update(&mut cx, |this, cx| {
10597                this.symbols(&envelope.payload.query, cx)
10598            })
10599            .await?;
10600
10601        Ok(proto::GetProjectSymbolsResponse {
10602            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10603        })
10604    }
10605
10606    pub async fn handle_restart_language_servers(
10607        this: Entity<Self>,
10608        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10609        mut cx: AsyncApp,
10610    ) -> Result<proto::Ack> {
10611        this.update(&mut cx, |lsp_store, cx| {
10612            let buffers =
10613                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10614            lsp_store.restart_language_servers_for_buffers(
10615                buffers,
10616                envelope
10617                    .payload
10618                    .only_servers
10619                    .into_iter()
10620                    .filter_map(|selector| {
10621                        Some(match selector.selector? {
10622                            proto::language_server_selector::Selector::ServerId(server_id) => {
10623                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10624                            }
10625                            proto::language_server_selector::Selector::Name(name) => {
10626                                LanguageServerSelector::Name(LanguageServerName(
10627                                    SharedString::from(name),
10628                                ))
10629                            }
10630                        })
10631                    })
10632                    .collect(),
10633                cx,
10634            );
10635        });
10636
10637        Ok(proto::Ack {})
10638    }
10639
10640    pub async fn handle_stop_language_servers(
10641        lsp_store: Entity<Self>,
10642        envelope: TypedEnvelope<proto::StopLanguageServers>,
10643        mut cx: AsyncApp,
10644    ) -> Result<proto::Ack> {
10645        lsp_store.update(&mut cx, |lsp_store, cx| {
10646            if envelope.payload.all
10647                && envelope.payload.also_servers.is_empty()
10648                && envelope.payload.buffer_ids.is_empty()
10649            {
10650                lsp_store.stop_all_language_servers(cx);
10651            } else {
10652                let buffers =
10653                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10654                lsp_store
10655                    .stop_language_servers_for_buffers(
10656                        buffers,
10657                        envelope
10658                            .payload
10659                            .also_servers
10660                            .into_iter()
10661                            .filter_map(|selector| {
10662                                Some(match selector.selector? {
10663                                    proto::language_server_selector::Selector::ServerId(
10664                                        server_id,
10665                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10666                                        server_id,
10667                                    )),
10668                                    proto::language_server_selector::Selector::Name(name) => {
10669                                        LanguageServerSelector::Name(LanguageServerName(
10670                                            SharedString::from(name),
10671                                        ))
10672                                    }
10673                                })
10674                            })
10675                            .collect(),
10676                        cx,
10677                    )
10678                    .detach_and_log_err(cx);
10679            }
10680        });
10681
10682        Ok(proto::Ack {})
10683    }
10684
10685    pub async fn handle_cancel_language_server_work(
10686        lsp_store: Entity<Self>,
10687        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10688        mut cx: AsyncApp,
10689    ) -> Result<proto::Ack> {
10690        lsp_store.update(&mut cx, |lsp_store, cx| {
10691            if let Some(work) = envelope.payload.work {
10692                match work {
10693                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10694                        let buffers =
10695                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10696                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10697                    }
10698                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10699                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10700                        let token = work
10701                            .token
10702                            .map(|token| {
10703                                ProgressToken::from_proto(token)
10704                                    .context("invalid work progress token")
10705                            })
10706                            .transpose()?;
10707                        lsp_store.cancel_language_server_work(server_id, token, cx);
10708                    }
10709                }
10710            }
10711            anyhow::Ok(())
10712        })?;
10713
10714        Ok(proto::Ack {})
10715    }
10716
10717    fn buffer_ids_to_buffers(
10718        &mut self,
10719        buffer_ids: impl Iterator<Item = u64>,
10720        cx: &mut Context<Self>,
10721    ) -> Vec<Entity<Buffer>> {
10722        buffer_ids
10723            .into_iter()
10724            .flat_map(|buffer_id| {
10725                self.buffer_store
10726                    .read(cx)
10727                    .get(BufferId::new(buffer_id).log_err()?)
10728            })
10729            .collect::<Vec<_>>()
10730    }
10731
10732    async fn handle_apply_additional_edits_for_completion(
10733        this: Entity<Self>,
10734        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10735        mut cx: AsyncApp,
10736    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10737        let (buffer, completion, all_commit_ranges) = this.update(&mut cx, |this, cx| {
10738            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10739            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10740            let completion = Self::deserialize_completion(
10741                envelope.payload.completion.context("invalid completion")?,
10742            )?;
10743            let all_commit_ranges = envelope
10744                .payload
10745                .all_commit_ranges
10746                .into_iter()
10747                .map(language::proto::deserialize_anchor_range)
10748                .collect::<Result<Vec<_>, _>>()?;
10749            anyhow::Ok((buffer, completion, all_commit_ranges))
10750        })?;
10751
10752        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10753            this.apply_additional_edits_for_completion(
10754                buffer,
10755                Rc::new(RefCell::new(Box::new([Completion {
10756                    replace_range: completion.replace_range,
10757                    new_text: completion.new_text,
10758                    source: completion.source,
10759                    documentation: None,
10760                    label: CodeLabel::default(),
10761                    match_start: None,
10762                    snippet_deduplication_key: None,
10763                    insert_text_mode: None,
10764                    icon_path: None,
10765                    confirm: None,
10766                }]))),
10767                0,
10768                false,
10769                all_commit_ranges,
10770                cx,
10771            )
10772        });
10773
10774        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10775            transaction: apply_additional_edits
10776                .await?
10777                .as_ref()
10778                .map(language::proto::serialize_transaction),
10779        })
10780    }
10781
10782    pub fn last_formatting_failure(&self) -> Option<&str> {
10783        self.last_formatting_failure.as_deref()
10784    }
10785
10786    pub fn reset_last_formatting_failure(&mut self) {
10787        self.last_formatting_failure = None;
10788    }
10789
10790    pub fn environment_for_buffer(
10791        &self,
10792        buffer: &Entity<Buffer>,
10793        cx: &mut Context<Self>,
10794    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10795        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10796            environment.update(cx, |env, cx| {
10797                env.buffer_environment(buffer, &self.worktree_store, cx)
10798            })
10799        } else {
10800            Task::ready(None).shared()
10801        }
10802    }
10803
10804    pub fn format(
10805        &mut self,
10806        buffers: HashSet<Entity<Buffer>>,
10807        target: LspFormatTarget,
10808        push_to_history: bool,
10809        trigger: FormatTrigger,
10810        cx: &mut Context<Self>,
10811    ) -> Task<anyhow::Result<ProjectTransaction>> {
10812        let logger = zlog::scoped!("format");
10813        if self.as_local().is_some() {
10814            zlog::trace!(logger => "Formatting locally");
10815            let logger = zlog::scoped!(logger => "local");
10816            let buffers = buffers
10817                .into_iter()
10818                .map(|buffer_handle| {
10819                    let buffer = buffer_handle.read(cx);
10820                    let buffer_abs_path = File::from_dyn(buffer.file())
10821                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10822
10823                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10824                })
10825                .collect::<Vec<_>>();
10826
10827            cx.spawn(async move |lsp_store, cx| {
10828                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10829
10830                for (handle, abs_path, id) in buffers {
10831                    let env = lsp_store
10832                        .update(cx, |lsp_store, cx| {
10833                            lsp_store.environment_for_buffer(&handle, cx)
10834                        })?
10835                        .await;
10836
10837                    let ranges = match &target {
10838                        LspFormatTarget::Buffers => None,
10839                        LspFormatTarget::Ranges(ranges) => {
10840                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10841                        }
10842                    };
10843
10844                    formattable_buffers.push(FormattableBuffer {
10845                        handle,
10846                        abs_path,
10847                        env,
10848                        ranges,
10849                    });
10850                }
10851                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10852
10853                let format_timer = zlog::time!(logger => "Formatting buffers");
10854                let result = LocalLspStore::format_locally(
10855                    lsp_store.clone(),
10856                    formattable_buffers,
10857                    push_to_history,
10858                    trigger,
10859                    logger,
10860                    cx,
10861                )
10862                .await;
10863                format_timer.end();
10864
10865                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10866
10867                lsp_store.update(cx, |lsp_store, _| {
10868                    lsp_store.update_last_formatting_failure(&result);
10869                })?;
10870
10871                result
10872            })
10873        } else if let Some((client, project_id)) = self.upstream_client() {
10874            zlog::trace!(logger => "Formatting remotely");
10875            let logger = zlog::scoped!(logger => "remote");
10876
10877            let buffer_ranges = match &target {
10878                LspFormatTarget::Buffers => Vec::new(),
10879                LspFormatTarget::Ranges(ranges) => ranges
10880                    .iter()
10881                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10882                        buffer_id: buffer_id.to_proto(),
10883                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10884                    })
10885                    .collect(),
10886            };
10887
10888            let buffer_store = self.buffer_store();
10889            cx.spawn(async move |lsp_store, cx| {
10890                zlog::trace!(logger => "Sending remote format request");
10891                let request_timer = zlog::time!(logger => "remote format request");
10892                let result = client
10893                    .request(proto::FormatBuffers {
10894                        project_id,
10895                        trigger: trigger as i32,
10896                        buffer_ids: buffers
10897                            .iter()
10898                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10899                            .collect(),
10900                        buffer_ranges,
10901                    })
10902                    .await
10903                    .and_then(|result| result.transaction.context("missing transaction"));
10904                request_timer.end();
10905
10906                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10907
10908                lsp_store.update(cx, |lsp_store, _| {
10909                    lsp_store.update_last_formatting_failure(&result);
10910                })?;
10911
10912                let transaction_response = result?;
10913                let _timer = zlog::time!(logger => "deserializing project transaction");
10914                buffer_store
10915                    .update(cx, |buffer_store, cx| {
10916                        buffer_store.deserialize_project_transaction(
10917                            transaction_response,
10918                            push_to_history,
10919                            cx,
10920                        )
10921                    })
10922                    .await
10923            })
10924        } else {
10925            zlog::trace!(logger => "Not formatting");
10926            Task::ready(Ok(ProjectTransaction::default()))
10927        }
10928    }
10929
10930    async fn handle_format_buffers(
10931        this: Entity<Self>,
10932        envelope: TypedEnvelope<proto::FormatBuffers>,
10933        mut cx: AsyncApp,
10934    ) -> Result<proto::FormatBuffersResponse> {
10935        let sender_id = envelope.original_sender_id().unwrap_or_default();
10936        let format = this.update(&mut cx, |this, cx| {
10937            let mut buffers = HashSet::default();
10938            for buffer_id in &envelope.payload.buffer_ids {
10939                let buffer_id = BufferId::new(*buffer_id)?;
10940                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10941            }
10942
10943            let target = if envelope.payload.buffer_ranges.is_empty() {
10944                LspFormatTarget::Buffers
10945            } else {
10946                let mut ranges_map = BTreeMap::new();
10947                for buffer_range in &envelope.payload.buffer_ranges {
10948                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10949                    let ranges: Result<Vec<_>> = buffer_range
10950                        .ranges
10951                        .iter()
10952                        .map(|range| {
10953                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10954                        })
10955                        .collect();
10956                    ranges_map.insert(buffer_id, ranges?);
10957                }
10958                LspFormatTarget::Ranges(ranges_map)
10959            };
10960
10961            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10962            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10963        })?;
10964
10965        let project_transaction = format.await?;
10966        let project_transaction = this.update(&mut cx, |this, cx| {
10967            this.buffer_store.update(cx, |buffer_store, cx| {
10968                buffer_store.serialize_project_transaction_for_peer(
10969                    project_transaction,
10970                    sender_id,
10971                    cx,
10972                )
10973            })
10974        });
10975        Ok(proto::FormatBuffersResponse {
10976            transaction: Some(project_transaction),
10977        })
10978    }
10979
10980    async fn handle_apply_code_action_kind(
10981        this: Entity<Self>,
10982        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10983        mut cx: AsyncApp,
10984    ) -> Result<proto::ApplyCodeActionKindResponse> {
10985        let sender_id = envelope.original_sender_id().unwrap_or_default();
10986        let format = this.update(&mut cx, |this, cx| {
10987            let mut buffers = HashSet::default();
10988            for buffer_id in &envelope.payload.buffer_ids {
10989                let buffer_id = BufferId::new(*buffer_id)?;
10990                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10991            }
10992            let kind = match envelope.payload.kind.as_str() {
10993                "" => CodeActionKind::EMPTY,
10994                "quickfix" => CodeActionKind::QUICKFIX,
10995                "refactor" => CodeActionKind::REFACTOR,
10996                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10997                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10998                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10999                "source" => CodeActionKind::SOURCE,
11000                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
11001                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
11002                _ => anyhow::bail!(
11003                    "Invalid code action kind {}",
11004                    envelope.payload.kind.as_str()
11005                ),
11006            };
11007            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
11008        })?;
11009
11010        let project_transaction = format.await?;
11011        let project_transaction = this.update(&mut cx, |this, cx| {
11012            this.buffer_store.update(cx, |buffer_store, cx| {
11013                buffer_store.serialize_project_transaction_for_peer(
11014                    project_transaction,
11015                    sender_id,
11016                    cx,
11017                )
11018            })
11019        });
11020        Ok(proto::ApplyCodeActionKindResponse {
11021            transaction: Some(project_transaction),
11022        })
11023    }
11024
11025    async fn shutdown_language_server(
11026        server_state: Option<LanguageServerState>,
11027        name: LanguageServerName,
11028        cx: &mut AsyncApp,
11029    ) {
11030        let server = match server_state {
11031            Some(LanguageServerState::Starting { startup, .. }) => {
11032                let mut timer = cx
11033                    .background_executor()
11034                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
11035                    .fuse();
11036
11037                select! {
11038                    server = startup.fuse() => server,
11039                    () = timer => {
11040                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
11041                        None
11042                    },
11043                }
11044            }
11045
11046            Some(LanguageServerState::Running { server, .. }) => Some(server),
11047
11048            None => None,
11049        };
11050
11051        let Some(server) = server else { return };
11052        if let Some(shutdown) = server.shutdown() {
11053            shutdown.await;
11054        }
11055    }
11056
11057    // Returns a list of all of the worktrees which no longer have a language server and the root path
11058    // for the stopped server
11059    fn stop_local_language_server(
11060        &mut self,
11061        server_id: LanguageServerId,
11062        cx: &mut Context<Self>,
11063    ) -> Task<()> {
11064        let local = match &mut self.mode {
11065            LspStoreMode::Local(local) => local,
11066            _ => {
11067                return Task::ready(());
11068            }
11069        };
11070
11071        // Remove this server ID from all entries in the given worktree.
11072        local
11073            .language_server_ids
11074            .retain(|_, state| state.id != server_id);
11075        self.buffer_store.update(cx, |buffer_store, cx| {
11076            for buffer in buffer_store.buffers() {
11077                buffer.update(cx, |buffer, cx| {
11078                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
11079                    buffer.set_completion_triggers(server_id, Default::default(), cx);
11080                });
11081            }
11082        });
11083
11084        let mut cleared_paths: Vec<ProjectPath> = Vec::new();
11085        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
11086            summaries.retain(|path, summaries_by_server_id| {
11087                if summaries_by_server_id.remove(&server_id).is_some() {
11088                    if let Some((client, project_id)) = self.downstream_client.clone() {
11089                        client
11090                            .send(proto::UpdateDiagnosticSummary {
11091                                project_id,
11092                                worktree_id: worktree_id.to_proto(),
11093                                summary: Some(proto::DiagnosticSummary {
11094                                    path: path.as_ref().to_proto(),
11095                                    language_server_id: server_id.0 as u64,
11096                                    error_count: 0,
11097                                    warning_count: 0,
11098                                }),
11099                                more_summaries: Vec::new(),
11100                            })
11101                            .log_err();
11102                    }
11103                    cleared_paths.push(ProjectPath {
11104                        worktree_id: *worktree_id,
11105                        path: path.clone(),
11106                    });
11107                    !summaries_by_server_id.is_empty()
11108                } else {
11109                    true
11110                }
11111            });
11112        }
11113        if !cleared_paths.is_empty() {
11114            cx.emit(LspStoreEvent::DiagnosticsUpdated {
11115                server_id,
11116                paths: cleared_paths,
11117            });
11118        }
11119
11120        let local = self.as_local_mut().unwrap();
11121        for diagnostics in local.diagnostics.values_mut() {
11122            diagnostics.retain(|_, diagnostics_by_server_id| {
11123                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11124                    diagnostics_by_server_id.remove(ix);
11125                    !diagnostics_by_server_id.is_empty()
11126                } else {
11127                    true
11128                }
11129            });
11130        }
11131        local.language_server_watched_paths.remove(&server_id);
11132
11133        let server_state = local.language_servers.remove(&server_id);
11134        self.cleanup_lsp_data(server_id);
11135        let name = self
11136            .language_server_statuses
11137            .remove(&server_id)
11138            .map(|status| status.name)
11139            .or_else(|| {
11140                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11141                    Some(adapter.name())
11142                } else {
11143                    None
11144                }
11145            });
11146
11147        if let Some(name) = name {
11148            log::info!("stopping language server {name}");
11149            self.languages
11150                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11151            cx.notify();
11152
11153            return cx.spawn(async move |lsp_store, cx| {
11154                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11155                lsp_store
11156                    .update(cx, |lsp_store, cx| {
11157                        lsp_store
11158                            .languages
11159                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11160                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11161                        cx.notify();
11162                    })
11163                    .ok();
11164            });
11165        }
11166
11167        if server_state.is_some() {
11168            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11169        }
11170        Task::ready(())
11171    }
11172
11173    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11174        self.shutdown_all_language_servers(cx).detach();
11175    }
11176
11177    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11178        if let Some((client, project_id)) = self.upstream_client() {
11179            let request = client.request(proto::StopLanguageServers {
11180                project_id,
11181                buffer_ids: Vec::new(),
11182                also_servers: Vec::new(),
11183                all: true,
11184            });
11185            cx.background_spawn(async move {
11186                request.await.ok();
11187            })
11188        } else {
11189            let Some(local) = self.as_local_mut() else {
11190                return Task::ready(());
11191            };
11192            let language_servers_to_stop = local
11193                .language_server_ids
11194                .values()
11195                .map(|state| state.id)
11196                .collect();
11197            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11198            let tasks = language_servers_to_stop
11199                .into_iter()
11200                .map(|server| self.stop_local_language_server(server, cx))
11201                .collect::<Vec<_>>();
11202            cx.background_spawn(async move {
11203                futures::future::join_all(tasks).await;
11204            })
11205        }
11206    }
11207
11208    pub fn restart_all_language_servers(&mut self, cx: &mut Context<Self>) {
11209        let buffers = self.buffer_store.read(cx).buffers().collect();
11210        self.restart_language_servers_for_buffers(buffers, HashSet::default(), cx);
11211    }
11212
11213    pub fn restart_language_servers_for_buffers(
11214        &mut self,
11215        buffers: Vec<Entity<Buffer>>,
11216        only_restart_servers: HashSet<LanguageServerSelector>,
11217        cx: &mut Context<Self>,
11218    ) {
11219        if let Some((client, project_id)) = self.upstream_client() {
11220            let request = client.request(proto::RestartLanguageServers {
11221                project_id,
11222                buffer_ids: buffers
11223                    .into_iter()
11224                    .map(|b| b.read(cx).remote_id().to_proto())
11225                    .collect(),
11226                only_servers: only_restart_servers
11227                    .into_iter()
11228                    .map(|selector| {
11229                        let selector = match selector {
11230                            LanguageServerSelector::Id(language_server_id) => {
11231                                proto::language_server_selector::Selector::ServerId(
11232                                    language_server_id.to_proto(),
11233                                )
11234                            }
11235                            LanguageServerSelector::Name(language_server_name) => {
11236                                proto::language_server_selector::Selector::Name(
11237                                    language_server_name.to_string(),
11238                                )
11239                            }
11240                        };
11241                        proto::LanguageServerSelector {
11242                            selector: Some(selector),
11243                        }
11244                    })
11245                    .collect(),
11246                all: false,
11247            });
11248            cx.background_spawn(request).detach_and_log_err(cx);
11249        } else {
11250            let stop_task = if only_restart_servers.is_empty() {
11251                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11252            } else {
11253                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11254            };
11255            cx.spawn(async move |lsp_store, cx| {
11256                stop_task.await;
11257                lsp_store.update(cx, |lsp_store, cx| {
11258                    for buffer in buffers {
11259                        lsp_store.register_buffer_with_language_servers(
11260                            &buffer,
11261                            only_restart_servers.clone(),
11262                            true,
11263                            cx,
11264                        );
11265                    }
11266                })
11267            })
11268            .detach();
11269        }
11270    }
11271
11272    pub fn stop_language_servers_for_buffers(
11273        &mut self,
11274        buffers: Vec<Entity<Buffer>>,
11275        also_stop_servers: HashSet<LanguageServerSelector>,
11276        cx: &mut Context<Self>,
11277    ) -> Task<Result<()>> {
11278        if let Some((client, project_id)) = self.upstream_client() {
11279            let request = client.request(proto::StopLanguageServers {
11280                project_id,
11281                buffer_ids: buffers
11282                    .into_iter()
11283                    .map(|b| b.read(cx).remote_id().to_proto())
11284                    .collect(),
11285                also_servers: also_stop_servers
11286                    .into_iter()
11287                    .map(|selector| {
11288                        let selector = match selector {
11289                            LanguageServerSelector::Id(language_server_id) => {
11290                                proto::language_server_selector::Selector::ServerId(
11291                                    language_server_id.to_proto(),
11292                                )
11293                            }
11294                            LanguageServerSelector::Name(language_server_name) => {
11295                                proto::language_server_selector::Selector::Name(
11296                                    language_server_name.to_string(),
11297                                )
11298                            }
11299                        };
11300                        proto::LanguageServerSelector {
11301                            selector: Some(selector),
11302                        }
11303                    })
11304                    .collect(),
11305                all: false,
11306            });
11307            cx.background_spawn(async move {
11308                let _ = request.await?;
11309                Ok(())
11310            })
11311        } else {
11312            let task =
11313                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11314            cx.background_spawn(async move {
11315                task.await;
11316                Ok(())
11317            })
11318        }
11319    }
11320
11321    fn stop_local_language_servers_for_buffers(
11322        &mut self,
11323        buffers: &[Entity<Buffer>],
11324        also_stop_servers: HashSet<LanguageServerSelector>,
11325        cx: &mut Context<Self>,
11326    ) -> Task<()> {
11327        let Some(local) = self.as_local_mut() else {
11328            return Task::ready(());
11329        };
11330        let mut language_server_names_to_stop = BTreeSet::default();
11331        let mut language_servers_to_stop = also_stop_servers
11332            .into_iter()
11333            .flat_map(|selector| match selector {
11334                LanguageServerSelector::Id(id) => Some(id),
11335                LanguageServerSelector::Name(name) => {
11336                    language_server_names_to_stop.insert(name);
11337                    None
11338                }
11339            })
11340            .collect::<BTreeSet<_>>();
11341
11342        let mut covered_worktrees = HashSet::default();
11343        for buffer in buffers {
11344            buffer.update(cx, |buffer, cx| {
11345                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11346                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11347                    && covered_worktrees.insert(worktree_id)
11348                {
11349                    language_server_names_to_stop.retain(|name| {
11350                        let old_ids_count = language_servers_to_stop.len();
11351                        let all_language_servers_with_this_name = local
11352                            .language_server_ids
11353                            .iter()
11354                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11355                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11356                        old_ids_count == language_servers_to_stop.len()
11357                    });
11358                }
11359            });
11360        }
11361        for name in language_server_names_to_stop {
11362            language_servers_to_stop.extend(
11363                local
11364                    .language_server_ids
11365                    .iter()
11366                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11367            );
11368        }
11369
11370        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11371        let tasks = language_servers_to_stop
11372            .into_iter()
11373            .map(|server| self.stop_local_language_server(server, cx))
11374            .collect::<Vec<_>>();
11375
11376        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11377    }
11378
11379    #[cfg(any(test, feature = "test-support"))]
11380    pub fn update_diagnostics(
11381        &mut self,
11382        server_id: LanguageServerId,
11383        diagnostics: lsp::PublishDiagnosticsParams,
11384        result_id: Option<SharedString>,
11385        source_kind: DiagnosticSourceKind,
11386        disk_based_sources: &[String],
11387        cx: &mut Context<Self>,
11388    ) -> Result<()> {
11389        self.merge_lsp_diagnostics(
11390            source_kind,
11391            vec![DocumentDiagnosticsUpdate {
11392                diagnostics,
11393                result_id,
11394                server_id,
11395                disk_based_sources: Cow::Borrowed(disk_based_sources),
11396                registration_id: None,
11397            }],
11398            |_, _, _| false,
11399            cx,
11400        )
11401    }
11402
11403    pub fn merge_lsp_diagnostics(
11404        &mut self,
11405        source_kind: DiagnosticSourceKind,
11406        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11407        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11408        cx: &mut Context<Self>,
11409    ) -> Result<()> {
11410        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11411        let updates = lsp_diagnostics
11412            .into_iter()
11413            .filter_map(|update| {
11414                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11415                Some(DocumentDiagnosticsUpdate {
11416                    diagnostics: self.lsp_to_document_diagnostics(
11417                        abs_path,
11418                        source_kind,
11419                        update.server_id,
11420                        update.diagnostics,
11421                        &update.disk_based_sources,
11422                        update.registration_id.clone(),
11423                    ),
11424                    result_id: update.result_id,
11425                    server_id: update.server_id,
11426                    disk_based_sources: update.disk_based_sources,
11427                    registration_id: update.registration_id,
11428                })
11429            })
11430            .collect();
11431        self.merge_diagnostic_entries(updates, merge, cx)?;
11432        Ok(())
11433    }
11434
11435    fn lsp_to_document_diagnostics(
11436        &mut self,
11437        document_abs_path: PathBuf,
11438        source_kind: DiagnosticSourceKind,
11439        server_id: LanguageServerId,
11440        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11441        disk_based_sources: &[String],
11442        registration_id: Option<SharedString>,
11443    ) -> DocumentDiagnostics {
11444        let mut diagnostics = Vec::default();
11445        let mut primary_diagnostic_group_ids = HashMap::default();
11446        let mut sources_by_group_id = HashMap::default();
11447        let mut supporting_diagnostics = HashMap::default();
11448
11449        let adapter = self.language_server_adapter_for_id(server_id);
11450
11451        // Ensure that primary diagnostics are always the most severe
11452        lsp_diagnostics
11453            .diagnostics
11454            .sort_by_key(|item| item.severity);
11455
11456        for diagnostic in &lsp_diagnostics.diagnostics {
11457            let source = diagnostic.source.as_ref();
11458            let range = range_from_lsp(diagnostic.range);
11459            let is_supporting = diagnostic
11460                .related_information
11461                .as_ref()
11462                .is_some_and(|infos| {
11463                    infos.iter().any(|info| {
11464                        primary_diagnostic_group_ids.contains_key(&(
11465                            source,
11466                            diagnostic.code.clone(),
11467                            range_from_lsp(info.location.range),
11468                        ))
11469                    })
11470                });
11471
11472            let is_unnecessary = diagnostic
11473                .tags
11474                .as_ref()
11475                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11476
11477            let underline = self
11478                .language_server_adapter_for_id(server_id)
11479                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11480
11481            if is_supporting {
11482                supporting_diagnostics.insert(
11483                    (source, diagnostic.code.clone(), range),
11484                    (diagnostic.severity, is_unnecessary),
11485                );
11486            } else {
11487                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11488                let is_disk_based =
11489                    source.is_some_and(|source| disk_based_sources.contains(source));
11490
11491                sources_by_group_id.insert(group_id, source);
11492                primary_diagnostic_group_ids
11493                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11494
11495                diagnostics.push(DiagnosticEntry {
11496                    range,
11497                    diagnostic: Diagnostic {
11498                        source: diagnostic.source.clone(),
11499                        source_kind,
11500                        code: diagnostic.code.clone(),
11501                        code_description: diagnostic
11502                            .code_description
11503                            .as_ref()
11504                            .and_then(|d| d.href.clone()),
11505                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11506                        markdown: adapter.as_ref().and_then(|adapter| {
11507                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11508                        }),
11509                        message: diagnostic.message.trim().to_string(),
11510                        group_id,
11511                        is_primary: true,
11512                        is_disk_based,
11513                        is_unnecessary,
11514                        underline,
11515                        data: diagnostic.data.clone(),
11516                        registration_id: registration_id.clone(),
11517                    },
11518                });
11519                if let Some(infos) = &diagnostic.related_information {
11520                    for info in infos {
11521                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11522                            let range = range_from_lsp(info.location.range);
11523                            diagnostics.push(DiagnosticEntry {
11524                                range,
11525                                diagnostic: Diagnostic {
11526                                    source: diagnostic.source.clone(),
11527                                    source_kind,
11528                                    code: diagnostic.code.clone(),
11529                                    code_description: diagnostic
11530                                        .code_description
11531                                        .as_ref()
11532                                        .and_then(|d| d.href.clone()),
11533                                    severity: DiagnosticSeverity::INFORMATION,
11534                                    markdown: adapter.as_ref().and_then(|adapter| {
11535                                        adapter.diagnostic_message_to_markdown(&info.message)
11536                                    }),
11537                                    message: info.message.trim().to_string(),
11538                                    group_id,
11539                                    is_primary: false,
11540                                    is_disk_based,
11541                                    is_unnecessary: false,
11542                                    underline,
11543                                    data: diagnostic.data.clone(),
11544                                    registration_id: registration_id.clone(),
11545                                },
11546                            });
11547                        }
11548                    }
11549                }
11550            }
11551        }
11552
11553        for entry in &mut diagnostics {
11554            let diagnostic = &mut entry.diagnostic;
11555            if !diagnostic.is_primary {
11556                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11557                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11558                    source,
11559                    diagnostic.code.clone(),
11560                    entry.range.clone(),
11561                )) {
11562                    if let Some(severity) = severity {
11563                        diagnostic.severity = severity;
11564                    }
11565                    diagnostic.is_unnecessary = is_unnecessary;
11566                }
11567            }
11568        }
11569
11570        DocumentDiagnostics {
11571            diagnostics,
11572            document_abs_path,
11573            version: lsp_diagnostics.version,
11574        }
11575    }
11576
11577    fn insert_newly_running_language_server(
11578        &mut self,
11579        adapter: Arc<CachedLspAdapter>,
11580        language_server: Arc<LanguageServer>,
11581        server_id: LanguageServerId,
11582        key: LanguageServerSeed,
11583        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11584        cx: &mut Context<Self>,
11585    ) {
11586        let Some(local) = self.as_local_mut() else {
11587            return;
11588        };
11589        // If the language server for this key doesn't match the server id, don't store the
11590        // server. Which will cause it to be dropped, killing the process
11591        if local
11592            .language_server_ids
11593            .get(&key)
11594            .map(|state| state.id != server_id)
11595            .unwrap_or(false)
11596        {
11597            return;
11598        }
11599
11600        // Update language_servers collection with Running variant of LanguageServerState
11601        // indicating that the server is up and running and ready
11602        let workspace_folders = workspace_folders.lock().clone();
11603        language_server.set_workspace_folders(workspace_folders);
11604
11605        let workspace_diagnostics_refresh_tasks = language_server
11606            .capabilities()
11607            .diagnostic_provider
11608            .and_then(|provider| {
11609                local
11610                    .language_server_dynamic_registrations
11611                    .entry(server_id)
11612                    .or_default()
11613                    .diagnostics
11614                    .entry(None)
11615                    .or_insert(provider.clone());
11616                let workspace_refresher =
11617                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11618
11619                Some((None, workspace_refresher))
11620            })
11621            .into_iter()
11622            .collect();
11623        local.language_servers.insert(
11624            server_id,
11625            LanguageServerState::Running {
11626                workspace_diagnostics_refresh_tasks,
11627                adapter: adapter.clone(),
11628                server: language_server.clone(),
11629                simulate_disk_based_diagnostics_completion: None,
11630            },
11631        );
11632        local
11633            .languages
11634            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11635        if let Some(file_ops_caps) = language_server
11636            .capabilities()
11637            .workspace
11638            .as_ref()
11639            .and_then(|ws| ws.file_operations.as_ref())
11640        {
11641            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11642            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11643            if did_rename_caps.or(will_rename_caps).is_some() {
11644                let watcher = RenamePathsWatchedForServer::default()
11645                    .with_did_rename_patterns(did_rename_caps)
11646                    .with_will_rename_patterns(will_rename_caps);
11647                local
11648                    .language_server_paths_watched_for_rename
11649                    .insert(server_id, watcher);
11650            }
11651        }
11652
11653        self.language_server_statuses.insert(
11654            server_id,
11655            LanguageServerStatus {
11656                name: language_server.name(),
11657                server_version: language_server.version(),
11658                server_readable_version: language_server.readable_version(),
11659                pending_work: Default::default(),
11660                has_pending_diagnostic_updates: false,
11661                progress_tokens: Default::default(),
11662                worktree: Some(key.worktree_id),
11663                binary: Some(language_server.binary().clone()),
11664                configuration: Some(language_server.configuration().clone()),
11665                workspace_folders: language_server.workspace_folders(),
11666                process_id: language_server.process_id(),
11667            },
11668        );
11669
11670        cx.emit(LspStoreEvent::LanguageServerAdded(
11671            server_id,
11672            language_server.name(),
11673            Some(key.worktree_id),
11674        ));
11675
11676        let server_capabilities = language_server.capabilities();
11677        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11678            downstream_client
11679                .send(proto::StartLanguageServer {
11680                    project_id: *project_id,
11681                    server: Some(proto::LanguageServer {
11682                        id: server_id.to_proto(),
11683                        name: language_server.name().to_string(),
11684                        worktree_id: Some(key.worktree_id.to_proto()),
11685                    }),
11686                    capabilities: serde_json::to_string(&server_capabilities)
11687                        .expect("serializing server LSP capabilities"),
11688                })
11689                .log_err();
11690        }
11691        self.lsp_server_capabilities
11692            .insert(server_id, server_capabilities);
11693
11694        // Tell the language server about every open buffer in the worktree that matches the language.
11695        // Also check for buffers in worktrees that reused this server
11696        let mut worktrees_using_server = vec![key.worktree_id];
11697        if let Some(local) = self.as_local() {
11698            // Find all worktrees that have this server in their language server tree
11699            for (worktree_id, servers) in &local.lsp_tree.instances {
11700                if *worktree_id != key.worktree_id {
11701                    for server_map in servers.roots.values() {
11702                        if server_map
11703                            .values()
11704                            .any(|(node, _)| node.id() == Some(server_id))
11705                        {
11706                            worktrees_using_server.push(*worktree_id);
11707                        }
11708                    }
11709                }
11710            }
11711        }
11712
11713        let mut buffer_paths_registered = Vec::new();
11714        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11715            let mut lsp_adapters = HashMap::default();
11716            for buffer_handle in buffer_store.buffers() {
11717                let buffer = buffer_handle.read(cx);
11718                let file = match File::from_dyn(buffer.file()) {
11719                    Some(file) => file,
11720                    None => continue,
11721                };
11722                let language = match buffer.language() {
11723                    Some(language) => language,
11724                    None => continue,
11725                };
11726
11727                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11728                    || !lsp_adapters
11729                        .entry(language.name())
11730                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11731                        .iter()
11732                        .any(|a| a.name == key.name)
11733                {
11734                    continue;
11735                }
11736                // didOpen
11737                let file = match file.as_local() {
11738                    Some(file) => file,
11739                    None => continue,
11740                };
11741
11742                let local = self.as_local_mut().unwrap();
11743
11744                let buffer_id = buffer.remote_id();
11745                if local.registered_buffers.contains_key(&buffer_id) {
11746                    let abs_path = file.abs_path(cx);
11747                    let uri = match lsp::Uri::from_file_path(&abs_path) {
11748                        Ok(uri) => uri,
11749                        Err(()) => {
11750                            log::error!("failed to convert path to URI: {:?}", abs_path);
11751                            continue;
11752                        }
11753                    };
11754
11755                    let versions = local
11756                        .buffer_snapshots
11757                        .entry(buffer_id)
11758                        .or_default()
11759                        .entry(server_id)
11760                        .and_modify(|_| {
11761                            assert!(
11762                            false,
11763                            "There should not be an existing snapshot for a newly inserted buffer"
11764                        )
11765                        })
11766                        .or_insert_with(|| {
11767                            vec![LspBufferSnapshot {
11768                                version: 0,
11769                                snapshot: buffer.text_snapshot(),
11770                            }]
11771                        });
11772
11773                    let snapshot = versions.last().unwrap();
11774                    let version = snapshot.version;
11775                    let initial_snapshot = &snapshot.snapshot;
11776                    language_server.register_buffer(
11777                        uri,
11778                        adapter.language_id(&language.name()),
11779                        version,
11780                        initial_snapshot.text(),
11781                    );
11782                    buffer_paths_registered.push((buffer_id, abs_path));
11783                    local
11784                        .buffers_opened_in_servers
11785                        .entry(buffer_id)
11786                        .or_default()
11787                        .insert(server_id);
11788                }
11789                buffer_handle.update(cx, |buffer, cx| {
11790                    buffer.set_completion_triggers(
11791                        server_id,
11792                        language_server
11793                            .capabilities()
11794                            .completion_provider
11795                            .as_ref()
11796                            .and_then(|provider| {
11797                                provider
11798                                    .trigger_characters
11799                                    .as_ref()
11800                                    .map(|characters| characters.iter().cloned().collect())
11801                            })
11802                            .unwrap_or_default(),
11803                        cx,
11804                    )
11805                });
11806            }
11807        });
11808
11809        for (buffer_id, abs_path) in buffer_paths_registered {
11810            cx.emit(LspStoreEvent::LanguageServerUpdate {
11811                language_server_id: server_id,
11812                name: Some(adapter.name()),
11813                message: proto::update_language_server::Variant::RegisteredForBuffer(
11814                    proto::RegisteredForBuffer {
11815                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11816                        buffer_id: buffer_id.to_proto(),
11817                    },
11818                ),
11819            });
11820        }
11821
11822        cx.notify();
11823    }
11824
11825    pub fn language_servers_running_disk_based_diagnostics(
11826        &self,
11827    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11828        self.language_server_statuses
11829            .iter()
11830            .filter_map(|(id, status)| {
11831                if status.has_pending_diagnostic_updates {
11832                    Some(*id)
11833                } else {
11834                    None
11835                }
11836            })
11837    }
11838
11839    pub(crate) fn cancel_language_server_work_for_buffers(
11840        &mut self,
11841        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11842        cx: &mut Context<Self>,
11843    ) {
11844        if let Some((client, project_id)) = self.upstream_client() {
11845            let request = client.request(proto::CancelLanguageServerWork {
11846                project_id,
11847                work: Some(proto::cancel_language_server_work::Work::Buffers(
11848                    proto::cancel_language_server_work::Buffers {
11849                        buffer_ids: buffers
11850                            .into_iter()
11851                            .map(|b| b.read(cx).remote_id().to_proto())
11852                            .collect(),
11853                    },
11854                )),
11855            });
11856            cx.background_spawn(request).detach_and_log_err(cx);
11857        } else if let Some(local) = self.as_local() {
11858            let servers = buffers
11859                .into_iter()
11860                .flat_map(|buffer| {
11861                    buffer.update(cx, |buffer, cx| {
11862                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11863                    })
11864                })
11865                .collect::<HashSet<_>>();
11866            for server_id in servers {
11867                self.cancel_language_server_work(server_id, None, cx);
11868            }
11869        }
11870    }
11871
11872    pub(crate) fn cancel_language_server_work(
11873        &mut self,
11874        server_id: LanguageServerId,
11875        token_to_cancel: Option<ProgressToken>,
11876        cx: &mut Context<Self>,
11877    ) {
11878        if let Some(local) = self.as_local() {
11879            let status = self.language_server_statuses.get(&server_id);
11880            let server = local.language_servers.get(&server_id);
11881            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11882            {
11883                for (token, progress) in &status.pending_work {
11884                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11885                        && token != token_to_cancel
11886                    {
11887                        continue;
11888                    }
11889                    if progress.is_cancellable {
11890                        server
11891                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11892                                WorkDoneProgressCancelParams {
11893                                    token: token.to_lsp(),
11894                                },
11895                            )
11896                            .ok();
11897                    }
11898                }
11899            }
11900        } else if let Some((client, project_id)) = self.upstream_client() {
11901            let request = client.request(proto::CancelLanguageServerWork {
11902                project_id,
11903                work: Some(
11904                    proto::cancel_language_server_work::Work::LanguageServerWork(
11905                        proto::cancel_language_server_work::LanguageServerWork {
11906                            language_server_id: server_id.to_proto(),
11907                            token: token_to_cancel.map(|token| token.to_proto()),
11908                        },
11909                    ),
11910                ),
11911            });
11912            cx.background_spawn(request).detach_and_log_err(cx);
11913        }
11914    }
11915
11916    fn register_supplementary_language_server(
11917        &mut self,
11918        id: LanguageServerId,
11919        name: LanguageServerName,
11920        server: Arc<LanguageServer>,
11921        cx: &mut Context<Self>,
11922    ) {
11923        if let Some(local) = self.as_local_mut() {
11924            local
11925                .supplementary_language_servers
11926                .insert(id, (name.clone(), server));
11927            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11928        }
11929    }
11930
11931    fn unregister_supplementary_language_server(
11932        &mut self,
11933        id: LanguageServerId,
11934        cx: &mut Context<Self>,
11935    ) {
11936        if let Some(local) = self.as_local_mut() {
11937            local.supplementary_language_servers.remove(&id);
11938            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11939        }
11940    }
11941
11942    pub(crate) fn supplementary_language_servers(
11943        &self,
11944    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11945        self.as_local().into_iter().flat_map(|local| {
11946            local
11947                .supplementary_language_servers
11948                .iter()
11949                .map(|(id, (name, _))| (*id, name.clone()))
11950        })
11951    }
11952
11953    pub fn language_server_adapter_for_id(
11954        &self,
11955        id: LanguageServerId,
11956    ) -> Option<Arc<CachedLspAdapter>> {
11957        if let Some(local) = self.as_local()
11958            && let Some(LanguageServerState::Running { adapter, .. }) =
11959                local.language_servers.get(&id)
11960        {
11961            return Some(adapter.clone());
11962        }
11963        // In remote (SSH/collab) mode there are no local `language_servers`, but
11964        // `language_server_statuses` is kept in sync with the upstream and carries each
11965        // server's registered name, which is enough to look the adapter up in the registry.
11966        let name = &self.language_server_statuses.get(&id)?.name;
11967        self.languages.adapter_for_name(name)
11968    }
11969
11970    pub(super) fn update_local_worktree_language_servers(
11971        &mut self,
11972        worktree_handle: &Entity<Worktree>,
11973        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11974        cx: &mut Context<Self>,
11975    ) {
11976        if changes.is_empty() {
11977            return;
11978        }
11979
11980        let Some(local) = self.as_local() else { return };
11981
11982        local.prettier_store.update(cx, |prettier_store, cx| {
11983            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11984        });
11985
11986        let worktree_id = worktree_handle.read(cx).id();
11987        let mut language_server_ids = local
11988            .language_server_ids
11989            .iter()
11990            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11991            .collect::<Vec<_>>();
11992        language_server_ids.sort();
11993        language_server_ids.dedup();
11994
11995        // let abs_path = worktree_handle.read(cx).abs_path();
11996        for server_id in &language_server_ids {
11997            if let Some(LanguageServerState::Running { server, .. }) =
11998                local.language_servers.get(server_id)
11999                && let Some(watched_paths) = local
12000                    .language_server_watched_paths
12001                    .get(server_id)
12002                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
12003            {
12004                let params = lsp::DidChangeWatchedFilesParams {
12005                    changes: changes
12006                        .iter()
12007                        .filter_map(|(path, _, change)| {
12008                            if !watched_paths.is_match(path.as_std_path()) {
12009                                return None;
12010                            }
12011                            let typ = match change {
12012                                PathChange::Loaded => return None,
12013                                PathChange::Added => lsp::FileChangeType::CREATED,
12014                                PathChange::Removed => lsp::FileChangeType::DELETED,
12015                                PathChange::Updated => lsp::FileChangeType::CHANGED,
12016                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
12017                            };
12018                            let uri = lsp::Uri::from_file_path(
12019                                worktree_handle.read(cx).absolutize(&path),
12020                            )
12021                            .ok()?;
12022                            Some(lsp::FileEvent { uri, typ })
12023                        })
12024                        .collect(),
12025                };
12026                if !params.changes.is_empty() {
12027                    server
12028                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
12029                        .ok();
12030                }
12031            }
12032        }
12033        for (path, _, _) in changes {
12034            if let Some(file_name) = path.file_name()
12035                && local.watched_manifest_filenames.contains(file_name)
12036            {
12037                self.request_workspace_config_refresh();
12038                break;
12039            }
12040        }
12041    }
12042
12043    pub fn wait_for_remote_buffer(
12044        &mut self,
12045        id: BufferId,
12046        cx: &mut Context<Self>,
12047    ) -> Task<Result<Entity<Buffer>>> {
12048        self.buffer_store.update(cx, |buffer_store, cx| {
12049            buffer_store.wait_for_remote_buffer(id, cx)
12050        })
12051    }
12052
12053    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
12054        let mut result = proto::Symbol {
12055            language_server_name: symbol.language_server_name.0.to_string(),
12056            source_worktree_id: symbol.source_worktree_id.to_proto(),
12057            language_server_id: symbol.source_language_server_id.to_proto(),
12058            name: symbol.name.clone(),
12059            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
12060            start: Some(proto::PointUtf16 {
12061                row: symbol.range.start.0.row,
12062                column: symbol.range.start.0.column,
12063            }),
12064            end: Some(proto::PointUtf16 {
12065                row: symbol.range.end.0.row,
12066                column: symbol.range.end.0.column,
12067            }),
12068            worktree_id: Default::default(),
12069            path: Default::default(),
12070            signature: Default::default(),
12071            container_name: symbol.container_name.clone(),
12072        };
12073        match &symbol.path {
12074            SymbolLocation::InProject(path) => {
12075                result.worktree_id = path.worktree_id.to_proto();
12076                result.path = path.path.to_proto();
12077            }
12078            SymbolLocation::OutsideProject {
12079                abs_path,
12080                signature,
12081            } => {
12082                result.path = abs_path.to_string_lossy().into_owned();
12083                result.signature = signature.to_vec();
12084            }
12085        }
12086        result
12087    }
12088
12089    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
12090        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
12091        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
12092        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
12093
12094        let path = if serialized_symbol.signature.is_empty() {
12095            SymbolLocation::InProject(ProjectPath {
12096                worktree_id,
12097                path: RelPath::from_proto(&serialized_symbol.path)
12098                    .context("invalid symbol path")?,
12099            })
12100        } else {
12101            SymbolLocation::OutsideProject {
12102                abs_path: Path::new(&serialized_symbol.path).into(),
12103                signature: serialized_symbol
12104                    .signature
12105                    .try_into()
12106                    .map_err(|_| anyhow!("invalid signature"))?,
12107            }
12108        };
12109
12110        let start = serialized_symbol.start.context("invalid start")?;
12111        let end = serialized_symbol.end.context("invalid end")?;
12112        Ok(CoreSymbol {
12113            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12114            source_worktree_id,
12115            source_language_server_id: LanguageServerId::from_proto(
12116                serialized_symbol.language_server_id,
12117            ),
12118            path,
12119            name: serialized_symbol.name,
12120            range: Unclipped(PointUtf16::new(start.row, start.column))
12121                ..Unclipped(PointUtf16::new(end.row, end.column)),
12122            kind,
12123            container_name: serialized_symbol.container_name,
12124        })
12125    }
12126
12127    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12128        let mut serialized_completion = proto::Completion {
12129            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12130            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12131            new_text: completion.new_text.clone(),
12132            ..proto::Completion::default()
12133        };
12134        match &completion.source {
12135            CompletionSource::Lsp {
12136                insert_range,
12137                server_id,
12138                lsp_completion,
12139                lsp_defaults,
12140                resolved,
12141            } => {
12142                let (old_insert_start, old_insert_end) = insert_range
12143                    .as_ref()
12144                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12145                    .unzip();
12146
12147                serialized_completion.old_insert_start = old_insert_start;
12148                serialized_completion.old_insert_end = old_insert_end;
12149                serialized_completion.source = proto::completion::Source::Lsp as i32;
12150                serialized_completion.server_id = server_id.0 as u64;
12151                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12152                serialized_completion.lsp_defaults = lsp_defaults
12153                    .as_deref()
12154                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12155                serialized_completion.resolved = *resolved;
12156            }
12157            CompletionSource::BufferWord {
12158                word_range,
12159                resolved,
12160            } => {
12161                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12162                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12163                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12164                serialized_completion.resolved = *resolved;
12165            }
12166            CompletionSource::Custom => {
12167                serialized_completion.source = proto::completion::Source::Custom as i32;
12168                serialized_completion.resolved = true;
12169            }
12170            CompletionSource::Dap { sort_text } => {
12171                serialized_completion.source = proto::completion::Source::Dap as i32;
12172                serialized_completion.sort_text = Some(sort_text.clone());
12173            }
12174        }
12175
12176        serialized_completion
12177    }
12178
12179    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12180        let old_replace_start = completion
12181            .old_replace_start
12182            .and_then(deserialize_anchor)
12183            .context("invalid old start")?;
12184        let old_replace_end = completion
12185            .old_replace_end
12186            .and_then(deserialize_anchor)
12187            .context("invalid old end")?;
12188        let insert_range = {
12189            match completion.old_insert_start.zip(completion.old_insert_end) {
12190                Some((start, end)) => {
12191                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12192                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12193                    Some(start..end)
12194                }
12195                None => None,
12196            }
12197        };
12198        Ok(CoreCompletion {
12199            replace_range: old_replace_start..old_replace_end,
12200            new_text: completion.new_text,
12201            source: match proto::completion::Source::from_i32(completion.source) {
12202                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12203                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12204                    insert_range,
12205                    server_id: LanguageServerId::from_proto(completion.server_id),
12206                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12207                    lsp_defaults: completion
12208                        .lsp_defaults
12209                        .as_deref()
12210                        .map(serde_json::from_slice)
12211                        .transpose()?,
12212                    resolved: completion.resolved,
12213                },
12214                Some(proto::completion::Source::BufferWord) => {
12215                    let word_range = completion
12216                        .buffer_word_start
12217                        .and_then(deserialize_anchor)
12218                        .context("invalid buffer word start")?
12219                        ..completion
12220                            .buffer_word_end
12221                            .and_then(deserialize_anchor)
12222                            .context("invalid buffer word end")?;
12223                    CompletionSource::BufferWord {
12224                        word_range,
12225                        resolved: completion.resolved,
12226                    }
12227                }
12228                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12229                    sort_text: completion
12230                        .sort_text
12231                        .context("expected sort text to exist")?,
12232                },
12233                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12234            },
12235        })
12236    }
12237
12238    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12239        let (kind, lsp_action) = match &action.lsp_action {
12240            LspAction::Action(code_action) => (
12241                proto::code_action::Kind::Action as i32,
12242                serde_json::to_vec(code_action).unwrap(),
12243            ),
12244            LspAction::Command(command) => (
12245                proto::code_action::Kind::Command as i32,
12246                serde_json::to_vec(command).unwrap(),
12247            ),
12248            LspAction::CodeLens(code_lens) => (
12249                proto::code_action::Kind::CodeLens as i32,
12250                serde_json::to_vec(code_lens).unwrap(),
12251            ),
12252        };
12253
12254        proto::CodeAction {
12255            server_id: action.server_id.0 as u64,
12256            start: Some(serialize_anchor(&action.range.start)),
12257            end: Some(serialize_anchor(&action.range.end)),
12258            lsp_action,
12259            kind,
12260            resolved: action.resolved,
12261        }
12262    }
12263
12264    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12265        let start = action
12266            .start
12267            .and_then(deserialize_anchor)
12268            .context("invalid start")?;
12269        let end = action
12270            .end
12271            .and_then(deserialize_anchor)
12272            .context("invalid end")?;
12273        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12274            Some(proto::code_action::Kind::Action) => {
12275                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12276            }
12277            Some(proto::code_action::Kind::Command) => {
12278                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12279            }
12280            Some(proto::code_action::Kind::CodeLens) => {
12281                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12282            }
12283            None => anyhow::bail!("Unknown action kind {}", action.kind),
12284        };
12285        Ok(CodeAction {
12286            server_id: LanguageServerId(action.server_id as usize),
12287            range: start..end,
12288            resolved: action.resolved,
12289            lsp_action,
12290        })
12291    }
12292
12293    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12294        match &formatting_result {
12295            Ok(_) => self.last_formatting_failure = None,
12296            Err(error) => {
12297                let error_string = format!("{error:#}");
12298                log::error!("Formatting failed: {error_string}");
12299                self.last_formatting_failure
12300                    .replace(error_string.lines().join(" "));
12301            }
12302        }
12303    }
12304
12305    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12306        self.lsp_server_capabilities.remove(&for_server);
12307        self.semantic_token_config.remove_server_data(for_server);
12308        for lsp_data in self.lsp_data.values_mut() {
12309            lsp_data.remove_server_data(for_server);
12310        }
12311        if let Some(local) = self.as_local_mut() {
12312            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12313            local
12314                .workspace_pull_diagnostics_result_ids
12315                .remove(&for_server);
12316            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12317                buffer_servers.remove(&for_server);
12318            }
12319        }
12320    }
12321
12322    pub fn result_id_for_buffer_pull(
12323        &self,
12324        server_id: LanguageServerId,
12325        buffer_id: BufferId,
12326        registration_id: &Option<SharedString>,
12327        cx: &App,
12328    ) -> Option<SharedString> {
12329        let abs_path = self
12330            .buffer_store
12331            .read(cx)
12332            .get(buffer_id)
12333            .and_then(|b| File::from_dyn(b.read(cx).file()))
12334            .map(|f| f.abs_path(cx))?;
12335        self.as_local()?
12336            .buffer_pull_diagnostics_result_ids
12337            .get(&server_id)?
12338            .get(registration_id)?
12339            .get(&abs_path)?
12340            .clone()
12341    }
12342
12343    /// Gets all result_ids for a workspace diagnostics pull request.
12344    /// First, it tries to find buffer's result_id retrieved via the diagnostics pull; if it fails, it falls back to the workspace disagnostics pull result_id.
12345    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12346    pub fn result_ids_for_workspace_refresh(
12347        &self,
12348        server_id: LanguageServerId,
12349        registration_id: &Option<SharedString>,
12350    ) -> HashMap<PathBuf, SharedString> {
12351        let Some(local) = self.as_local() else {
12352            return HashMap::default();
12353        };
12354        local
12355            .workspace_pull_diagnostics_result_ids
12356            .get(&server_id)
12357            .into_iter()
12358            .filter_map(|diagnostics| diagnostics.get(registration_id))
12359            .flatten()
12360            .filter_map(|(abs_path, result_id)| {
12361                let result_id = local
12362                    .buffer_pull_diagnostics_result_ids
12363                    .get(&server_id)
12364                    .and_then(|buffer_ids_result_ids| {
12365                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12366                    })
12367                    .cloned()
12368                    .flatten()
12369                    .or_else(|| result_id.clone())?;
12370                Some((abs_path.clone(), result_id))
12371            })
12372            .collect()
12373    }
12374
12375    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12376        if let Some(LanguageServerState::Running {
12377            workspace_diagnostics_refresh_tasks,
12378            ..
12379        }) = self
12380            .as_local_mut()
12381            .and_then(|local| local.language_servers.get_mut(&server_id))
12382        {
12383            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12384                diagnostics.refresh_tx.try_send(()).ok();
12385            }
12386        }
12387    }
12388
12389    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12390    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12391    /// which requires refreshing both workspace and document diagnostics.
12392    pub fn pull_document_diagnostics_for_server(
12393        &mut self,
12394        server_id: LanguageServerId,
12395        source_buffer_id: Option<BufferId>,
12396        cx: &mut Context<Self>,
12397    ) -> Shared<Task<()>> {
12398        let Some(local) = self.as_local_mut() else {
12399            return Task::ready(()).shared();
12400        };
12401        let mut buffers_to_refresh = HashSet::default();
12402        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12403            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12404                buffers_to_refresh.insert(*buffer_id);
12405            }
12406        }
12407
12408        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12409    }
12410
12411    pub fn pull_document_diagnostics_for_buffer_edit(
12412        &mut self,
12413        buffer_id: BufferId,
12414        cx: &mut Context<Self>,
12415    ) {
12416        let Some(local) = self.as_local_mut() else {
12417            return;
12418        };
12419        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12420        else {
12421            return;
12422        };
12423        for server_id in languages_servers {
12424            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12425        }
12426    }
12427
12428    fn apply_workspace_diagnostic_report(
12429        &mut self,
12430        server_id: LanguageServerId,
12431        report: lsp::WorkspaceDiagnosticReportResult,
12432        registration_id: Option<SharedString>,
12433        cx: &mut Context<Self>,
12434    ) {
12435        let mut workspace_diagnostics =
12436            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12437                report,
12438                server_id,
12439                registration_id,
12440            );
12441        workspace_diagnostics.retain(|d| match &d.diagnostics {
12442            LspPullDiagnostics::Response {
12443                server_id,
12444                registration_id,
12445                ..
12446            } => self.diagnostic_registration_exists(*server_id, registration_id),
12447            LspPullDiagnostics::Default => false,
12448        });
12449        let mut unchanged_buffers = HashMap::default();
12450        let workspace_diagnostics_updates = workspace_diagnostics
12451            .into_iter()
12452            .filter_map(
12453                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12454                    LspPullDiagnostics::Response {
12455                        server_id,
12456                        uri,
12457                        diagnostics,
12458                        registration_id,
12459                    } => Some((
12460                        server_id,
12461                        uri,
12462                        diagnostics,
12463                        workspace_diagnostics.version,
12464                        registration_id,
12465                    )),
12466                    LspPullDiagnostics::Default => None,
12467                },
12468            )
12469            .fold(
12470                HashMap::default(),
12471                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12472                    let (result_id, diagnostics) = match diagnostics {
12473                        PulledDiagnostics::Unchanged { result_id } => {
12474                            unchanged_buffers
12475                                .entry(new_registration_id.clone())
12476                                .or_insert_with(HashSet::default)
12477                                .insert(uri.clone());
12478                            (Some(result_id), Vec::new())
12479                        }
12480                        PulledDiagnostics::Changed {
12481                            result_id,
12482                            diagnostics,
12483                        } => (result_id, diagnostics),
12484                    };
12485                    let disk_based_sources = Cow::Owned(
12486                        self.language_server_adapter_for_id(server_id)
12487                            .as_ref()
12488                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12489                            .unwrap_or(&[])
12490                            .to_vec(),
12491                    );
12492
12493                    let Some(abs_path) = uri.to_file_path().ok() else {
12494                        return acc;
12495                    };
12496                    let Some((worktree, relative_path)) =
12497                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12498                    else {
12499                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12500                        return acc;
12501                    };
12502                    let worktree_id = worktree.read(cx).id();
12503                    let project_path = ProjectPath {
12504                        worktree_id,
12505                        path: relative_path,
12506                    };
12507                    if let Some(local_lsp_store) = self.as_local_mut() {
12508                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12509                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12510                    }
12511                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12512                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12513                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12514                        acc.entry(server_id)
12515                            .or_insert_with(HashMap::default)
12516                            .entry(new_registration_id.clone())
12517                            .or_insert_with(Vec::new)
12518                            .push(DocumentDiagnosticsUpdate {
12519                                server_id,
12520                                diagnostics: lsp::PublishDiagnosticsParams {
12521                                    uri,
12522                                    diagnostics,
12523                                    version,
12524                                },
12525                                result_id: result_id.map(SharedString::new),
12526                                disk_based_sources,
12527                                registration_id: new_registration_id,
12528                            });
12529                    }
12530                    acc
12531                },
12532            );
12533
12534        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12535            for (registration_id, diagnostic_updates) in diagnostic_updates {
12536                self.merge_lsp_diagnostics(
12537                    DiagnosticSourceKind::Pulled,
12538                    diagnostic_updates,
12539                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12540                        DiagnosticSourceKind::Pulled => {
12541                            old_diagnostic.registration_id != registration_id
12542                                || unchanged_buffers
12543                                    .get(&old_diagnostic.registration_id)
12544                                    .is_some_and(|unchanged_buffers| {
12545                                        unchanged_buffers.contains(&document_uri)
12546                                    })
12547                        }
12548                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12549                    },
12550                    cx,
12551                )
12552                .log_err();
12553            }
12554        }
12555    }
12556
12557    fn register_server_capabilities(
12558        &mut self,
12559        server_id: LanguageServerId,
12560        params: lsp::RegistrationParams,
12561        cx: &mut Context<Self>,
12562    ) -> anyhow::Result<()> {
12563        let server = self
12564            .language_server_for_id(server_id)
12565            .with_context(|| format!("no server {server_id} found"))?;
12566        for reg in params.registrations {
12567            match reg.method.as_str() {
12568                "workspace/didChangeWatchedFiles" => {
12569                    if let Some(options) = reg.register_options {
12570                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12571                            let caps = serde_json::from_value(options)?;
12572                            local_lsp_store
12573                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12574                            true
12575                        } else {
12576                            false
12577                        };
12578                        if notify {
12579                            notify_server_capabilities_updated(&server, cx);
12580                        }
12581                    }
12582                }
12583                "workspace/didChangeConfiguration" => {
12584                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12585                }
12586                "workspace/didChangeWorkspaceFolders" => {
12587                    // In this case register options is an empty object, we can ignore it
12588                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12589                        supported: Some(true),
12590                        change_notifications: Some(OneOf::Right(reg.id)),
12591                    };
12592                    server.update_capabilities(|capabilities| {
12593                        capabilities
12594                            .workspace
12595                            .get_or_insert_default()
12596                            .workspace_folders = Some(caps);
12597                    });
12598                    notify_server_capabilities_updated(&server, cx);
12599                }
12600                "workspace/symbol" => {
12601                    let options = parse_register_capabilities(reg)?;
12602                    server.update_capabilities(|capabilities| {
12603                        capabilities.workspace_symbol_provider = Some(options);
12604                    });
12605                    notify_server_capabilities_updated(&server, cx);
12606                }
12607                "workspace/fileOperations" => {
12608                    if let Some(options) = reg.register_options {
12609                        let caps = serde_json::from_value(options)?;
12610                        server.update_capabilities(|capabilities| {
12611                            capabilities
12612                                .workspace
12613                                .get_or_insert_default()
12614                                .file_operations = Some(caps);
12615                        });
12616                        notify_server_capabilities_updated(&server, cx);
12617                    }
12618                }
12619                "workspace/executeCommand" => {
12620                    if let Some(options) = reg.register_options {
12621                        let options = serde_json::from_value(options)?;
12622                        server.update_capabilities(|capabilities| {
12623                            capabilities.execute_command_provider = Some(options);
12624                        });
12625                        notify_server_capabilities_updated(&server, cx);
12626                    }
12627                }
12628                "textDocument/rangeFormatting" => {
12629                    let options = parse_register_capabilities(reg)?;
12630                    server.update_capabilities(|capabilities| {
12631                        capabilities.document_range_formatting_provider = Some(options);
12632                    });
12633                    notify_server_capabilities_updated(&server, cx);
12634                }
12635                "textDocument/onTypeFormatting" => {
12636                    if let Some(options) = reg
12637                        .register_options
12638                        .map(serde_json::from_value)
12639                        .transpose()?
12640                    {
12641                        server.update_capabilities(|capabilities| {
12642                            capabilities.document_on_type_formatting_provider = Some(options);
12643                        });
12644                        notify_server_capabilities_updated(&server, cx);
12645                    }
12646                }
12647                "textDocument/formatting" => {
12648                    let options = parse_register_capabilities(reg)?;
12649                    server.update_capabilities(|capabilities| {
12650                        capabilities.document_formatting_provider = Some(options);
12651                    });
12652                    notify_server_capabilities_updated(&server, cx);
12653                }
12654                "textDocument/rename" => {
12655                    let options = parse_register_capabilities(reg)?;
12656                    server.update_capabilities(|capabilities| {
12657                        capabilities.rename_provider = Some(options);
12658                    });
12659                    notify_server_capabilities_updated(&server, cx);
12660                }
12661                "textDocument/inlayHint" => {
12662                    let options = parse_register_capabilities(reg)?;
12663                    server.update_capabilities(|capabilities| {
12664                        capabilities.inlay_hint_provider = Some(options);
12665                    });
12666                    notify_server_capabilities_updated(&server, cx);
12667                }
12668                "textDocument/documentSymbol" => {
12669                    let options = parse_register_capabilities(reg)?;
12670                    server.update_capabilities(|capabilities| {
12671                        capabilities.document_symbol_provider = Some(options);
12672                    });
12673                    notify_server_capabilities_updated(&server, cx);
12674                }
12675                "textDocument/codeAction" => {
12676                    let options = parse_register_capabilities(reg)?;
12677                    let provider = match options {
12678                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12679                        OneOf::Right(caps) => caps,
12680                    };
12681                    server.update_capabilities(|capabilities| {
12682                        capabilities.code_action_provider = Some(provider);
12683                    });
12684                    notify_server_capabilities_updated(&server, cx);
12685                }
12686                "textDocument/definition" => {
12687                    let options = parse_register_capabilities(reg)?;
12688                    server.update_capabilities(|capabilities| {
12689                        capabilities.definition_provider = Some(options);
12690                    });
12691                    notify_server_capabilities_updated(&server, cx);
12692                }
12693                "textDocument/completion" => {
12694                    if let Some(caps) = reg
12695                        .register_options
12696                        .map(serde_json::from_value::<CompletionOptions>)
12697                        .transpose()?
12698                    {
12699                        server.update_capabilities(|capabilities| {
12700                            capabilities.completion_provider = Some(caps.clone());
12701                        });
12702
12703                        if let Some(local) = self.as_local() {
12704                            let mut buffers_with_language_server = Vec::new();
12705                            for handle in self.buffer_store.read(cx).buffers() {
12706                                let buffer_id = handle.read(cx).remote_id();
12707                                if local
12708                                    .buffers_opened_in_servers
12709                                    .get(&buffer_id)
12710                                    .filter(|s| s.contains(&server_id))
12711                                    .is_some()
12712                                {
12713                                    buffers_with_language_server.push(handle);
12714                                }
12715                            }
12716                            let triggers = caps
12717                                .trigger_characters
12718                                .unwrap_or_default()
12719                                .into_iter()
12720                                .collect::<BTreeSet<_>>();
12721                            for handle in buffers_with_language_server {
12722                                let triggers = triggers.clone();
12723                                let _ = handle.update(cx, move |buffer, cx| {
12724                                    buffer.set_completion_triggers(server_id, triggers, cx);
12725                                });
12726                            }
12727                        }
12728                        notify_server_capabilities_updated(&server, cx);
12729                    }
12730                }
12731                "textDocument/hover" => {
12732                    let options = parse_register_capabilities(reg)?;
12733                    let provider = match options {
12734                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12735                        OneOf::Right(caps) => caps,
12736                    };
12737                    server.update_capabilities(|capabilities| {
12738                        capabilities.hover_provider = Some(provider);
12739                    });
12740                    notify_server_capabilities_updated(&server, cx);
12741                }
12742                "textDocument/signatureHelp" => {
12743                    if let Some(caps) = reg
12744                        .register_options
12745                        .map(serde_json::from_value)
12746                        .transpose()?
12747                    {
12748                        server.update_capabilities(|capabilities| {
12749                            capabilities.signature_help_provider = Some(caps);
12750                        });
12751                        notify_server_capabilities_updated(&server, cx);
12752                    }
12753                }
12754                "textDocument/didChange" => {
12755                    if let Some(sync_kind) = reg
12756                        .register_options
12757                        .and_then(|opts| opts.get("syncKind").cloned())
12758                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12759                        .transpose()?
12760                    {
12761                        server.update_capabilities(|capabilities| {
12762                            let mut sync_options =
12763                                Self::take_text_document_sync_options(capabilities);
12764                            sync_options.change = Some(sync_kind);
12765                            capabilities.text_document_sync =
12766                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12767                        });
12768                        notify_server_capabilities_updated(&server, cx);
12769                    }
12770                }
12771                "textDocument/didSave" => {
12772                    if let Some(include_text) = reg
12773                        .register_options
12774                        .map(|opts| {
12775                            let transpose = opts
12776                                .get("includeText")
12777                                .cloned()
12778                                .map(serde_json::from_value::<Option<bool>>)
12779                                .transpose();
12780                            match transpose {
12781                                Ok(value) => Ok(value.flatten()),
12782                                Err(e) => Err(e),
12783                            }
12784                        })
12785                        .transpose()?
12786                    {
12787                        server.update_capabilities(|capabilities| {
12788                            let mut sync_options =
12789                                Self::take_text_document_sync_options(capabilities);
12790                            sync_options.save =
12791                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12792                                    include_text,
12793                                }));
12794                            capabilities.text_document_sync =
12795                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12796                        });
12797                        notify_server_capabilities_updated(&server, cx);
12798                    }
12799                }
12800                "textDocument/codeLens" => {
12801                    if let Some(caps) = reg
12802                        .register_options
12803                        .map(serde_json::from_value)
12804                        .transpose()?
12805                    {
12806                        server.update_capabilities(|capabilities| {
12807                            capabilities.code_lens_provider = Some(caps);
12808                        });
12809                        notify_server_capabilities_updated(&server, cx);
12810                    }
12811                }
12812                "textDocument/diagnostic" => {
12813                    if let Some(caps) = reg
12814                        .register_options
12815                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12816                        .transpose()?
12817                    {
12818                        let local = self
12819                            .as_local_mut()
12820                            .context("Expected LSP Store to be local")?;
12821                        let state = local
12822                            .language_servers
12823                            .get_mut(&server_id)
12824                            .context("Could not obtain Language Servers state")?;
12825                        local
12826                            .language_server_dynamic_registrations
12827                            .entry(server_id)
12828                            .or_default()
12829                            .diagnostics
12830                            .insert(Some(reg.id.clone()), caps.clone());
12831
12832                        let supports_workspace_diagnostics =
12833                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12834                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12835                                    diagnostic_options.workspace_diagnostics
12836                                }
12837                                DiagnosticServerCapabilities::RegistrationOptions(
12838                                    diagnostic_registration_options,
12839                                ) => {
12840                                    diagnostic_registration_options
12841                                        .diagnostic_options
12842                                        .workspace_diagnostics
12843                                }
12844                            };
12845
12846                        if supports_workspace_diagnostics(&caps) {
12847                            if let LanguageServerState::Running {
12848                                workspace_diagnostics_refresh_tasks,
12849                                ..
12850                            } = state
12851                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12852                                    Some(reg.id.clone()),
12853                                    caps.clone(),
12854                                    server.clone(),
12855                                    cx,
12856                                )
12857                            {
12858                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12859                            }
12860                        }
12861
12862                        server.update_capabilities(|capabilities| {
12863                            capabilities.diagnostic_provider = Some(caps);
12864                        });
12865
12866                        notify_server_capabilities_updated(&server, cx);
12867
12868                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12869                    }
12870                }
12871                "textDocument/documentColor" => {
12872                    let options = parse_register_capabilities(reg)?;
12873                    let provider = match options {
12874                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12875                        OneOf::Right(caps) => caps,
12876                    };
12877                    server.update_capabilities(|capabilities| {
12878                        capabilities.color_provider = Some(provider);
12879                    });
12880                    notify_server_capabilities_updated(&server, cx);
12881                }
12882                "textDocument/foldingRange" => {
12883                    let options = parse_register_capabilities(reg)?;
12884                    let provider = match options {
12885                        OneOf::Left(value) => lsp::FoldingRangeProviderCapability::Simple(value),
12886                        OneOf::Right(caps) => caps,
12887                    };
12888                    server.update_capabilities(|capabilities| {
12889                        capabilities.folding_range_provider = Some(provider);
12890                    });
12891                    notify_server_capabilities_updated(&server, cx);
12892                }
12893                _ => log::warn!("unhandled capability registration: {reg:?}"),
12894            }
12895        }
12896
12897        Ok(())
12898    }
12899
12900    fn unregister_server_capabilities(
12901        &mut self,
12902        server_id: LanguageServerId,
12903        params: lsp::UnregistrationParams,
12904        cx: &mut Context<Self>,
12905    ) -> anyhow::Result<()> {
12906        let server = self
12907            .language_server_for_id(server_id)
12908            .with_context(|| format!("no server {server_id} found"))?;
12909        for unreg in params.unregisterations.iter() {
12910            match unreg.method.as_str() {
12911                "workspace/didChangeWatchedFiles" => {
12912                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12913                        local_lsp_store
12914                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12915                        true
12916                    } else {
12917                        false
12918                    };
12919                    if notify {
12920                        notify_server_capabilities_updated(&server, cx);
12921                    }
12922                }
12923                "workspace/didChangeConfiguration" => {
12924                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12925                }
12926                "workspace/didChangeWorkspaceFolders" => {
12927                    server.update_capabilities(|capabilities| {
12928                        capabilities
12929                            .workspace
12930                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12931                                workspace_folders: None,
12932                                file_operations: None,
12933                            })
12934                            .workspace_folders = None;
12935                    });
12936                    notify_server_capabilities_updated(&server, cx);
12937                }
12938                "workspace/symbol" => {
12939                    server.update_capabilities(|capabilities| {
12940                        capabilities.workspace_symbol_provider = None
12941                    });
12942                    notify_server_capabilities_updated(&server, cx);
12943                }
12944                "workspace/fileOperations" => {
12945                    server.update_capabilities(|capabilities| {
12946                        capabilities
12947                            .workspace
12948                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12949                                workspace_folders: None,
12950                                file_operations: None,
12951                            })
12952                            .file_operations = None;
12953                    });
12954                    notify_server_capabilities_updated(&server, cx);
12955                }
12956                "workspace/executeCommand" => {
12957                    server.update_capabilities(|capabilities| {
12958                        capabilities.execute_command_provider = None;
12959                    });
12960                    notify_server_capabilities_updated(&server, cx);
12961                }
12962                "textDocument/rangeFormatting" => {
12963                    server.update_capabilities(|capabilities| {
12964                        capabilities.document_range_formatting_provider = None
12965                    });
12966                    notify_server_capabilities_updated(&server, cx);
12967                }
12968                "textDocument/onTypeFormatting" => {
12969                    server.update_capabilities(|capabilities| {
12970                        capabilities.document_on_type_formatting_provider = None;
12971                    });
12972                    notify_server_capabilities_updated(&server, cx);
12973                }
12974                "textDocument/formatting" => {
12975                    server.update_capabilities(|capabilities| {
12976                        capabilities.document_formatting_provider = None;
12977                    });
12978                    notify_server_capabilities_updated(&server, cx);
12979                }
12980                "textDocument/rename" => {
12981                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12982                    notify_server_capabilities_updated(&server, cx);
12983                }
12984                "textDocument/codeAction" => {
12985                    server.update_capabilities(|capabilities| {
12986                        capabilities.code_action_provider = None;
12987                    });
12988                    notify_server_capabilities_updated(&server, cx);
12989                }
12990                "textDocument/definition" => {
12991                    server.update_capabilities(|capabilities| {
12992                        capabilities.definition_provider = None;
12993                    });
12994                    notify_server_capabilities_updated(&server, cx);
12995                }
12996                "textDocument/completion" => {
12997                    server.update_capabilities(|capabilities| {
12998                        capabilities.completion_provider = None;
12999                    });
13000                    notify_server_capabilities_updated(&server, cx);
13001                }
13002                "textDocument/hover" => {
13003                    server.update_capabilities(|capabilities| {
13004                        capabilities.hover_provider = None;
13005                    });
13006                    notify_server_capabilities_updated(&server, cx);
13007                }
13008                "textDocument/signatureHelp" => {
13009                    server.update_capabilities(|capabilities| {
13010                        capabilities.signature_help_provider = None;
13011                    });
13012                    notify_server_capabilities_updated(&server, cx);
13013                }
13014                "textDocument/didChange" => {
13015                    server.update_capabilities(|capabilities| {
13016                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
13017                        sync_options.change = None;
13018                        capabilities.text_document_sync =
13019                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
13020                    });
13021                    notify_server_capabilities_updated(&server, cx);
13022                }
13023                "textDocument/didSave" => {
13024                    server.update_capabilities(|capabilities| {
13025                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
13026                        sync_options.save = None;
13027                        capabilities.text_document_sync =
13028                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
13029                    });
13030                    notify_server_capabilities_updated(&server, cx);
13031                }
13032                "textDocument/codeLens" => {
13033                    server.update_capabilities(|capabilities| {
13034                        capabilities.code_lens_provider = None;
13035                    });
13036                    notify_server_capabilities_updated(&server, cx);
13037                }
13038                "textDocument/diagnostic" => {
13039                    let local = self
13040                        .as_local_mut()
13041                        .context("Expected LSP Store to be local")?;
13042
13043                    let state = local
13044                        .language_servers
13045                        .get_mut(&server_id)
13046                        .context("Could not obtain Language Servers state")?;
13047                    let registrations = local
13048                        .language_server_dynamic_registrations
13049                        .get_mut(&server_id)
13050                        .with_context(|| {
13051                            format!("Expected dynamic registration to exist for server {server_id}")
13052                        })?;
13053                    registrations.diagnostics
13054                        .remove(&Some(unreg.id.clone()))
13055                        .with_context(|| format!(
13056                            "Attempted to unregister non-existent diagnostic registration with ID {}",
13057                            unreg.id)
13058                        )?;
13059                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
13060
13061                    if let LanguageServerState::Running {
13062                        workspace_diagnostics_refresh_tasks,
13063                        ..
13064                    } = state
13065                    {
13066                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
13067                    }
13068
13069                    self.clear_unregistered_diagnostics(
13070                        server_id,
13071                        SharedString::from(unreg.id.clone()),
13072                        cx,
13073                    )?;
13074
13075                    if removed_last_diagnostic_provider {
13076                        server.update_capabilities(|capabilities| {
13077                            debug_assert!(capabilities.diagnostic_provider.is_some());
13078                            capabilities.diagnostic_provider = None;
13079                        });
13080                    }
13081
13082                    notify_server_capabilities_updated(&server, cx);
13083                }
13084                "textDocument/documentColor" => {
13085                    server.update_capabilities(|capabilities| {
13086                        capabilities.color_provider = None;
13087                    });
13088                    notify_server_capabilities_updated(&server, cx);
13089                }
13090                "textDocument/foldingRange" => {
13091                    server.update_capabilities(|capabilities| {
13092                        capabilities.folding_range_provider = None;
13093                    });
13094                    notify_server_capabilities_updated(&server, cx);
13095                }
13096                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
13097            }
13098        }
13099
13100        Ok(())
13101    }
13102
13103    fn clear_unregistered_diagnostics(
13104        &mut self,
13105        server_id: LanguageServerId,
13106        cleared_registration_id: SharedString,
13107        cx: &mut Context<Self>,
13108    ) -> anyhow::Result<()> {
13109        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13110
13111        self.buffer_store.update(cx, |buffer_store, cx| {
13112            for buffer_handle in buffer_store.buffers() {
13113                let buffer = buffer_handle.read(cx);
13114                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13115                let Some(abs_path) = abs_path else {
13116                    continue;
13117                };
13118                affected_abs_paths.insert(abs_path);
13119            }
13120        });
13121
13122        let local = self.as_local().context("Expected LSP Store to be local")?;
13123        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13124            let Some(worktree) = self
13125                .worktree_store
13126                .read(cx)
13127                .worktree_for_id(*worktree_id, cx)
13128            else {
13129                continue;
13130            };
13131
13132            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13133                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13134                    let has_matching_registration =
13135                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13136                            entry.diagnostic.registration_id.as_ref()
13137                                == Some(&cleared_registration_id)
13138                        });
13139                    if has_matching_registration {
13140                        let abs_path = worktree.read(cx).absolutize(rel_path);
13141                        affected_abs_paths.insert(abs_path);
13142                    }
13143                }
13144            }
13145        }
13146
13147        if affected_abs_paths.is_empty() {
13148            return Ok(());
13149        }
13150
13151        // Send a fake diagnostic update which clears the state for the registration ID
13152        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13153            affected_abs_paths
13154                .into_iter()
13155                .map(|abs_path| DocumentDiagnosticsUpdate {
13156                    diagnostics: DocumentDiagnostics {
13157                        diagnostics: Vec::new(),
13158                        document_abs_path: abs_path,
13159                        version: None,
13160                    },
13161                    result_id: None,
13162                    registration_id: Some(cleared_registration_id.clone()),
13163                    server_id,
13164                    disk_based_sources: Cow::Borrowed(&[]),
13165                })
13166                .collect();
13167
13168        let merge_registration_id = cleared_registration_id.clone();
13169        self.merge_diagnostic_entries(
13170            clears,
13171            move |_, diagnostic, _| {
13172                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13173                    diagnostic.registration_id != Some(merge_registration_id.clone())
13174                } else {
13175                    true
13176                }
13177            },
13178            cx,
13179        )?;
13180
13181        Ok(())
13182    }
13183
13184    async fn deduplicate_range_based_lsp_requests<T>(
13185        lsp_store: &Entity<Self>,
13186        server_id: Option<LanguageServerId>,
13187        lsp_request_id: LspRequestId,
13188        proto_request: &T::ProtoRequest,
13189        range: Range<Anchor>,
13190        cx: &mut AsyncApp,
13191    ) -> Result<()>
13192    where
13193        T: LspCommand,
13194        T::ProtoRequest: proto::LspRequestMessage,
13195    {
13196        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13197        let version = deserialize_version(proto_request.buffer_version());
13198        let buffer = lsp_store.update(cx, |this, cx| {
13199            this.buffer_store.read(cx).get_existing(buffer_id)
13200        })?;
13201        buffer
13202            .update(cx, |buffer, _| buffer.wait_for_version(version))
13203            .await?;
13204        lsp_store.update(cx, |lsp_store, cx| {
13205            let buffer_snapshot = buffer.read(cx).snapshot();
13206            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13207            let chunks_queried_for = lsp_data
13208                .inlay_hints
13209                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13210                .collect::<Vec<_>>();
13211            match chunks_queried_for.as_slice() {
13212                &[chunk] => {
13213                    let key = LspKey {
13214                        request_type: TypeId::of::<T>(),
13215                        server_queried: server_id,
13216                    };
13217                    let previous_request = lsp_data
13218                        .chunk_lsp_requests
13219                        .entry(key)
13220                        .or_default()
13221                        .insert(chunk, lsp_request_id);
13222                    if let Some((previous_request, running_requests)) =
13223                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13224                    {
13225                        running_requests.remove(&previous_request);
13226                    }
13227                }
13228                _ambiguous_chunks => {
13229                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13230                    // there, a buffer version-based check will be performed and outdated requests discarded.
13231                }
13232            }
13233            anyhow::Ok(())
13234        })?;
13235
13236        Ok(())
13237    }
13238
13239    async fn query_lsp_locally<T>(
13240        lsp_store: Entity<Self>,
13241        for_server_id: Option<LanguageServerId>,
13242        sender_id: proto::PeerId,
13243        lsp_request_id: LspRequestId,
13244        proto_request: T::ProtoRequest,
13245        position: Option<Anchor>,
13246        cx: &mut AsyncApp,
13247    ) -> Result<()>
13248    where
13249        T: LspCommand + Clone,
13250        T::ProtoRequest: proto::LspRequestMessage,
13251        <T::ProtoRequest as proto::RequestMessage>::Response:
13252            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13253    {
13254        let (buffer_version, buffer) =
13255            Self::wait_for_buffer_version::<T>(&lsp_store, &proto_request, cx).await?;
13256        let request =
13257            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13258        let key = LspKey {
13259            request_type: TypeId::of::<T>(),
13260            server_queried: for_server_id,
13261        };
13262        lsp_store.update(cx, |lsp_store, cx| {
13263            let request_task = match for_server_id {
13264                Some(server_id) => {
13265                    let server_task = lsp_store.request_lsp(
13266                        buffer.clone(),
13267                        LanguageServerToQuery::Other(server_id),
13268                        request.clone(),
13269                        cx,
13270                    );
13271                    cx.background_spawn(async move {
13272                        let mut responses = Vec::new();
13273                        match server_task.await {
13274                            Ok(response) => responses.push((server_id, response)),
13275                            // rust-analyzer likes to error with this when its still loading up
13276                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13277                            Err(e) => log::error!(
13278                                "Error handling response for request {request:?}: {e:#}"
13279                            ),
13280                        }
13281                        responses
13282                    })
13283                }
13284                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13285            };
13286            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13287            if T::ProtoRequest::stop_previous_requests() {
13288                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13289                    lsp_requests.clear();
13290                }
13291            }
13292            lsp_data.lsp_requests.entry(key).or_default().insert(
13293                lsp_request_id,
13294                cx.spawn(async move |lsp_store, cx| {
13295                    let response = request_task.await;
13296                    lsp_store
13297                        .update(cx, |lsp_store, cx| {
13298                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13299                            {
13300                                let response = response
13301                                    .into_iter()
13302                                    .map(|(server_id, response)| {
13303                                        (
13304                                            server_id.to_proto(),
13305                                            T::response_to_proto(
13306                                                response,
13307                                                lsp_store,
13308                                                sender_id,
13309                                                &buffer_version,
13310                                                cx,
13311                                            )
13312                                            .into(),
13313                                        )
13314                                    })
13315                                    .collect::<HashMap<_, _>>();
13316                                match client.send_lsp_response::<T::ProtoRequest>(
13317                                    project_id,
13318                                    lsp_request_id,
13319                                    response,
13320                                ) {
13321                                    Ok(()) => {}
13322                                    Err(e) => {
13323                                        log::error!("Failed to send LSP response: {e:#}",)
13324                                    }
13325                                }
13326                            }
13327                        })
13328                        .ok();
13329                }),
13330            );
13331        });
13332        Ok(())
13333    }
13334
13335    async fn wait_for_buffer_version<T>(
13336        lsp_store: &Entity<Self>,
13337        proto_request: &T::ProtoRequest,
13338        cx: &mut AsyncApp,
13339    ) -> Result<(Global, Entity<Buffer>)>
13340    where
13341        T: LspCommand,
13342        T::ProtoRequest: proto::LspRequestMessage,
13343    {
13344        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13345        let version = deserialize_version(proto_request.buffer_version());
13346        let buffer = lsp_store.update(cx, |this, cx| {
13347            this.buffer_store.read(cx).get_existing(buffer_id)
13348        })?;
13349        buffer
13350            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13351            .await?;
13352        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13353        Ok((buffer_version, buffer))
13354    }
13355
13356    fn take_text_document_sync_options(
13357        capabilities: &mut lsp::ServerCapabilities,
13358    ) -> lsp::TextDocumentSyncOptions {
13359        match capabilities.text_document_sync.take() {
13360            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13361            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13362                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13363                sync_options.change = Some(sync_kind);
13364                sync_options
13365            }
13366            None => lsp::TextDocumentSyncOptions::default(),
13367        }
13368    }
13369
13370    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13371        self.downstream_client.clone()
13372    }
13373
13374    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13375        self.worktree_store.clone()
13376    }
13377
13378    /// Gets what's stored in the LSP data for the given buffer.
13379    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13380        self.lsp_data.get_mut(&buffer_id)
13381    }
13382
13383    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13384    /// new [`BufferLspData`] will be created to replace the previous state.
13385    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13386        let (buffer_id, buffer_version) =
13387            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13388        let lsp_data = self
13389            .lsp_data
13390            .entry(buffer_id)
13391            .or_insert_with(|| BufferLspData::new(buffer, cx));
13392        if buffer_version.changed_since(&lsp_data.buffer_version) {
13393            // To send delta requests for semantic tokens, the previous tokens
13394            // need to be kept between buffer changes.
13395            let semantic_tokens = lsp_data.semantic_tokens.take();
13396            *lsp_data = BufferLspData::new(buffer, cx);
13397            lsp_data.semantic_tokens = semantic_tokens;
13398        }
13399        lsp_data
13400    }
13401}
13402
13403// Registration with registerOptions as null, should fallback to true.
13404// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13405fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13406    reg: lsp::Registration,
13407) -> Result<OneOf<bool, T>> {
13408    Ok(match reg.register_options {
13409        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13410        None => OneOf::Left(true),
13411    })
13412}
13413
13414fn server_capabilities_support_range_formatting(capabilities: &lsp::ServerCapabilities) -> bool {
13415    matches!(
13416        capabilities.document_range_formatting_provider.as_ref(),
13417        Some(provider) if *provider != OneOf::Left(false)
13418    )
13419}
13420
13421fn subscribe_to_binary_statuses(
13422    languages: &Arc<LanguageRegistry>,
13423    cx: &mut Context<'_, LspStore>,
13424) -> Task<()> {
13425    let mut server_statuses = languages.language_server_binary_statuses();
13426    cx.spawn(async move |lsp_store, cx| {
13427        while let Some((server_name, binary_status)) = server_statuses.next().await {
13428            if lsp_store
13429                .update(cx, |_, cx| {
13430                    let mut message = None;
13431                    let binary_status = match binary_status {
13432                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13433                        BinaryStatus::CheckingForUpdate => {
13434                            proto::ServerBinaryStatus::CheckingForUpdate
13435                        }
13436                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13437                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13438                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13439                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13440                        BinaryStatus::Failed { error } => {
13441                            message = Some(error);
13442                            proto::ServerBinaryStatus::Failed
13443                        }
13444                    };
13445                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13446                        // Binary updates are about the binary that might not have any language server id at that point.
13447                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13448                        language_server_id: LanguageServerId(0),
13449                        name: Some(server_name),
13450                        message: proto::update_language_server::Variant::StatusUpdate(
13451                            proto::StatusUpdate {
13452                                message,
13453                                status: Some(proto::status_update::Status::Binary(
13454                                    binary_status as i32,
13455                                )),
13456                            },
13457                        ),
13458                    });
13459                })
13460                .is_err()
13461            {
13462                break;
13463            }
13464        }
13465    })
13466}
13467
13468fn lsp_workspace_diagnostics_refresh(
13469    registration_id: Option<String>,
13470    options: DiagnosticServerCapabilities,
13471    server: Arc<LanguageServer>,
13472    cx: &mut Context<'_, LspStore>,
13473) -> Option<WorkspaceRefreshTask> {
13474    let identifier = workspace_diagnostic_identifier(&options)?;
13475    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13476
13477    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13478    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13479    refresh_tx.try_send(()).ok();
13480
13481    let request_timeout = ProjectSettings::get_global(cx)
13482        .global_lsp_settings
13483        .get_request_timeout();
13484
13485    // Clamp timeout duration at a minimum of [`DEFAULT_LSP_REQUEST_TIMEOUT`] to mitigate useless loops from re-trying connections with smaller timeouts from project settings.
13486    // This allows users to increase the duration if need be
13487    let timeout = if request_timeout != Duration::ZERO {
13488        request_timeout.max(DEFAULT_LSP_REQUEST_TIMEOUT)
13489    } else {
13490        request_timeout
13491    };
13492
13493    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13494        let mut attempts = 0;
13495        let max_attempts = 50;
13496        let mut requests = 0;
13497
13498        loop {
13499            let Some(()) = refresh_rx.recv().await else {
13500                return;
13501            };
13502
13503            'request: loop {
13504                requests += 1;
13505                if attempts > max_attempts {
13506                    log::error!(
13507                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13508                    );
13509                    return;
13510                }
13511                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13512                cx.background_executor()
13513                    .timer(Duration::from_millis(backoff_millis))
13514                    .await;
13515                attempts += 1;
13516
13517                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13518                    lsp_store
13519                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13520                        .into_iter()
13521                        .filter_map(|(abs_path, result_id)| {
13522                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13523                            Some(lsp::PreviousResultId {
13524                                uri,
13525                                value: result_id.to_string(),
13526                            })
13527                        })
13528                        .collect()
13529                }) else {
13530                    return;
13531                };
13532
13533                let token = if let Some(registration_id) = &registration_id {
13534                    format!(
13535                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13536                        server.server_id(),
13537                    )
13538                } else {
13539                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13540                };
13541
13542                progress_rx.try_recv().ok();
13543                let timer = server.request_timer(timeout).fuse();
13544                let progress = pin!(progress_rx.recv().fuse());
13545                let response_result = server
13546                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13547                        lsp::WorkspaceDiagnosticParams {
13548                            previous_result_ids,
13549                            identifier: identifier.clone(),
13550                            work_done_progress_params: Default::default(),
13551                            partial_result_params: lsp::PartialResultParams {
13552                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13553                            },
13554                        },
13555                        select(timer, progress).then(|either| match either {
13556                            Either::Left((message, ..)) => ready(message).left_future(),
13557                            Either::Right(..) => pending::<String>().right_future(),
13558                        }),
13559                    )
13560                    .await;
13561
13562                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13563                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13564                match response_result {
13565                    ConnectionResult::Timeout => {
13566                        log::error!("Timeout during workspace diagnostics pull");
13567                        continue 'request;
13568                    }
13569                    ConnectionResult::ConnectionReset => {
13570                        log::error!("Server closed a workspace diagnostics pull request");
13571                        continue 'request;
13572                    }
13573                    ConnectionResult::Result(Err(e)) => {
13574                        log::error!("Error during workspace diagnostics pull: {e:#}");
13575                        break 'request;
13576                    }
13577                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13578                        attempts = 0;
13579                        if lsp_store
13580                            .update(cx, |lsp_store, cx| {
13581                                lsp_store.apply_workspace_diagnostic_report(
13582                                    server.server_id(),
13583                                    pulled_diagnostics,
13584                                    registration_id_shared.clone(),
13585                                    cx,
13586                                )
13587                            })
13588                            .is_err()
13589                        {
13590                            return;
13591                        }
13592                        break 'request;
13593                    }
13594                }
13595            }
13596        }
13597    });
13598
13599    Some(WorkspaceRefreshTask {
13600        refresh_tx,
13601        progress_tx,
13602        task: workspace_query_language_server,
13603    })
13604}
13605
13606fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<SharedString> {
13607    match &options {
13608        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => diagnostic_options
13609            .identifier
13610            .as_deref()
13611            .map(SharedString::new),
13612        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13613            let diagnostic_options = &registration_options.diagnostic_options;
13614            diagnostic_options
13615                .identifier
13616                .as_deref()
13617                .map(SharedString::new)
13618        }
13619    }
13620}
13621
13622fn workspace_diagnostic_identifier(
13623    options: &DiagnosticServerCapabilities,
13624) -> Option<Option<String>> {
13625    match &options {
13626        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13627            if !diagnostic_options.workspace_diagnostics {
13628                return None;
13629            }
13630            Some(diagnostic_options.identifier.clone())
13631        }
13632        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13633            let diagnostic_options = &registration_options.diagnostic_options;
13634            if !diagnostic_options.workspace_diagnostics {
13635                return None;
13636            }
13637            Some(diagnostic_options.identifier.clone())
13638        }
13639    }
13640}
13641
13642fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13643    let CompletionSource::BufferWord {
13644        word_range,
13645        resolved,
13646    } = &mut completion.source
13647    else {
13648        return;
13649    };
13650    if *resolved {
13651        return;
13652    }
13653
13654    if completion.new_text
13655        != snapshot
13656            .text_for_range(word_range.clone())
13657            .collect::<String>()
13658    {
13659        return;
13660    }
13661
13662    let mut offset = 0;
13663    for chunk in snapshot.chunks(
13664        word_range.clone(),
13665        LanguageAwareStyling {
13666            tree_sitter: true,
13667            diagnostics: true,
13668        },
13669    ) {
13670        let end_offset = offset + chunk.text.len();
13671        if let Some(highlight_id) = chunk.syntax_highlight_id {
13672            completion
13673                .label
13674                .runs
13675                .push((offset..end_offset, highlight_id));
13676        }
13677        offset = end_offset;
13678    }
13679    *resolved = true;
13680}
13681
13682impl EventEmitter<LspStoreEvent> for LspStore {}
13683
13684fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13685    hover
13686        .contents
13687        .retain(|hover_block| !hover_block.text.trim().is_empty());
13688    if hover.contents.is_empty() {
13689        None
13690    } else {
13691        Some(hover)
13692    }
13693}
13694
13695async fn populate_labels_for_completions(
13696    new_completions: Vec<CoreCompletion>,
13697    language: Option<Arc<Language>>,
13698    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13699) -> Vec<Completion> {
13700    let lsp_completions = new_completions
13701        .iter()
13702        .filter_map(|new_completion| {
13703            new_completion
13704                .source
13705                .lsp_completion(true)
13706                .map(|lsp_completion| lsp_completion.into_owned())
13707        })
13708        .collect::<Vec<_>>();
13709
13710    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13711        lsp_adapter
13712            .labels_for_completions(&lsp_completions, language)
13713            .await
13714            .log_err()
13715            .unwrap_or_default()
13716    } else {
13717        Vec::new()
13718    }
13719    .into_iter()
13720    .fuse();
13721
13722    let mut completions = Vec::new();
13723    for completion in new_completions {
13724        match completion.source.lsp_completion(true) {
13725            Some(lsp_completion) => {
13726                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13727
13728                let mut label = labels.next().flatten().unwrap_or_else(|| {
13729                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13730                });
13731                ensure_uniform_list_compatible_label(&mut label);
13732                completions.push(Completion {
13733                    label,
13734                    documentation,
13735                    replace_range: completion.replace_range,
13736                    new_text: completion.new_text,
13737                    insert_text_mode: lsp_completion.insert_text_mode,
13738                    source: completion.source,
13739                    icon_path: None,
13740                    confirm: None,
13741                    match_start: None,
13742                    snippet_deduplication_key: None,
13743                });
13744            }
13745            None => {
13746                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13747                ensure_uniform_list_compatible_label(&mut label);
13748                completions.push(Completion {
13749                    label,
13750                    documentation: None,
13751                    replace_range: completion.replace_range,
13752                    new_text: completion.new_text,
13753                    source: completion.source,
13754                    insert_text_mode: None,
13755                    icon_path: None,
13756                    confirm: None,
13757                    match_start: None,
13758                    snippet_deduplication_key: None,
13759                });
13760            }
13761        }
13762    }
13763    completions
13764}
13765
13766#[derive(Debug)]
13767pub enum LanguageServerToQuery {
13768    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13769    FirstCapable,
13770    /// Query a specific language server.
13771    Other(LanguageServerId),
13772}
13773
13774#[derive(Default)]
13775struct RenamePathsWatchedForServer {
13776    did_rename: Vec<RenameActionPredicate>,
13777    will_rename: Vec<RenameActionPredicate>,
13778}
13779
13780impl RenamePathsWatchedForServer {
13781    fn with_did_rename_patterns(
13782        mut self,
13783        did_rename: Option<&FileOperationRegistrationOptions>,
13784    ) -> Self {
13785        if let Some(did_rename) = did_rename {
13786            self.did_rename = did_rename
13787                .filters
13788                .iter()
13789                .filter_map(|filter| filter.try_into().log_err())
13790                .collect();
13791        }
13792        self
13793    }
13794    fn with_will_rename_patterns(
13795        mut self,
13796        will_rename: Option<&FileOperationRegistrationOptions>,
13797    ) -> Self {
13798        if let Some(will_rename) = will_rename {
13799            self.will_rename = will_rename
13800                .filters
13801                .iter()
13802                .filter_map(|filter| filter.try_into().log_err())
13803                .collect();
13804        }
13805        self
13806    }
13807
13808    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13809        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13810    }
13811    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13812        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13813    }
13814}
13815
13816impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13817    type Error = globset::Error;
13818    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13819        Ok(Self {
13820            kind: ops.pattern.matches.clone(),
13821            glob: GlobBuilder::new(&ops.pattern.glob)
13822                .case_insensitive(
13823                    ops.pattern
13824                        .options
13825                        .as_ref()
13826                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13827                )
13828                .build()?
13829                .compile_matcher(),
13830        })
13831    }
13832}
13833struct RenameActionPredicate {
13834    glob: GlobMatcher,
13835    kind: Option<FileOperationPatternKind>,
13836}
13837
13838impl RenameActionPredicate {
13839    // Returns true if language server should be notified
13840    fn eval(&self, path: &str, is_dir: bool) -> bool {
13841        self.kind.as_ref().is_none_or(|kind| {
13842            let expected_kind = if is_dir {
13843                FileOperationPatternKind::Folder
13844            } else {
13845                FileOperationPatternKind::File
13846            };
13847            kind == &expected_kind
13848        }) && self.glob.is_match(path)
13849    }
13850}
13851
13852#[derive(Default)]
13853struct LanguageServerWatchedPaths {
13854    worktree_paths: HashMap<WorktreeId, GlobSet>,
13855    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13856}
13857
13858#[derive(Default)]
13859struct LanguageServerWatchedPathsBuilder {
13860    worktree_paths: HashMap<WorktreeId, GlobSet>,
13861    abs_paths: HashMap<Arc<Path>, GlobSet>,
13862}
13863
13864impl LanguageServerWatchedPathsBuilder {
13865    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13866        self.worktree_paths.insert(worktree_id, glob_set);
13867    }
13868    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13869        self.abs_paths.insert(path, glob_set);
13870    }
13871    fn build(
13872        self,
13873        fs: Arc<dyn Fs>,
13874        language_server_id: LanguageServerId,
13875        cx: &mut Context<LspStore>,
13876    ) -> LanguageServerWatchedPaths {
13877        let lsp_store = cx.weak_entity();
13878
13879        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13880        let abs_paths = self
13881            .abs_paths
13882            .into_iter()
13883            .map(|(abs_path, globset)| {
13884                let task = cx.spawn({
13885                    let abs_path = abs_path.clone();
13886                    let fs = fs.clone();
13887
13888                    let lsp_store = lsp_store.clone();
13889                    async move |_, cx| {
13890                        maybe!(async move {
13891                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13892                            while let Some(update) = push_updates.0.next().await {
13893                                let action = lsp_store
13894                                    .update(cx, |this, _| {
13895                                        let Some(local) = this.as_local() else {
13896                                            return ControlFlow::Break(());
13897                                        };
13898                                        let Some(watcher) = local
13899                                            .language_server_watched_paths
13900                                            .get(&language_server_id)
13901                                        else {
13902                                            return ControlFlow::Break(());
13903                                        };
13904                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13905                                            "Watched abs path is not registered with a watcher",
13906                                        );
13907                                        let matching_entries = update
13908                                            .into_iter()
13909                                            .filter(|event| globs.is_match(&event.path))
13910                                            .collect::<Vec<_>>();
13911                                        this.lsp_notify_abs_paths_changed(
13912                                            language_server_id,
13913                                            matching_entries,
13914                                        );
13915                                        ControlFlow::Continue(())
13916                                    })
13917                                    .ok()?;
13918
13919                                if action.is_break() {
13920                                    break;
13921                                }
13922                            }
13923                            Some(())
13924                        })
13925                        .await;
13926                    }
13927                });
13928                (abs_path, (globset, task))
13929            })
13930            .collect();
13931        LanguageServerWatchedPaths {
13932            worktree_paths: self.worktree_paths,
13933            abs_paths,
13934        }
13935    }
13936}
13937
13938struct LspBufferSnapshot {
13939    version: i32,
13940    snapshot: TextBufferSnapshot,
13941}
13942
13943/// A prompt requested by LSP server.
13944#[derive(Clone, Debug)]
13945pub struct LanguageServerPromptRequest {
13946    pub id: usize,
13947    pub level: PromptLevel,
13948    pub message: String,
13949    pub actions: Vec<MessageActionItem>,
13950    pub lsp_name: String,
13951    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13952}
13953
13954impl LanguageServerPromptRequest {
13955    pub fn new(
13956        level: PromptLevel,
13957        message: String,
13958        actions: Vec<MessageActionItem>,
13959        lsp_name: String,
13960        response_channel: smol::channel::Sender<MessageActionItem>,
13961    ) -> Self {
13962        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13963        LanguageServerPromptRequest {
13964            id,
13965            level,
13966            message,
13967            actions,
13968            lsp_name,
13969            response_channel,
13970        }
13971    }
13972    pub async fn respond(self, index: usize) -> Option<()> {
13973        if let Some(response) = self.actions.into_iter().nth(index) {
13974            self.response_channel.send(response).await.ok()
13975        } else {
13976            None
13977        }
13978    }
13979
13980    #[cfg(any(test, feature = "test-support"))]
13981    pub fn test(
13982        level: PromptLevel,
13983        message: String,
13984        actions: Vec<MessageActionItem>,
13985        lsp_name: String,
13986    ) -> Self {
13987        let (tx, _rx) = smol::channel::unbounded();
13988        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13989    }
13990}
13991impl PartialEq for LanguageServerPromptRequest {
13992    fn eq(&self, other: &Self) -> bool {
13993        self.message == other.message && self.actions == other.actions
13994    }
13995}
13996
13997#[derive(Clone, Debug, PartialEq)]
13998pub enum LanguageServerLogType {
13999    Log(MessageType),
14000    Trace { verbose_info: Option<String> },
14001    Rpc { received: bool },
14002}
14003
14004impl LanguageServerLogType {
14005    pub fn to_proto(&self) -> proto::language_server_log::LogType {
14006        match self {
14007            Self::Log(log_type) => {
14008                use proto::log_message::LogLevel;
14009                let level = match *log_type {
14010                    MessageType::ERROR => LogLevel::Error,
14011                    MessageType::WARNING => LogLevel::Warning,
14012                    MessageType::INFO => LogLevel::Info,
14013                    MessageType::LOG => LogLevel::Log,
14014                    other => {
14015                        log::warn!("Unknown lsp log message type: {other:?}");
14016                        LogLevel::Log
14017                    }
14018                };
14019                proto::language_server_log::LogType::Log(proto::LogMessage {
14020                    level: level as i32,
14021                })
14022            }
14023            Self::Trace { verbose_info } => {
14024                proto::language_server_log::LogType::Trace(proto::TraceMessage {
14025                    verbose_info: verbose_info.to_owned(),
14026                })
14027            }
14028            Self::Rpc { received } => {
14029                let kind = if *received {
14030                    proto::rpc_message::Kind::Received
14031                } else {
14032                    proto::rpc_message::Kind::Sent
14033                };
14034                let kind = kind as i32;
14035                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
14036            }
14037        }
14038    }
14039
14040    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
14041        use proto::log_message::LogLevel;
14042        use proto::rpc_message;
14043        match log_type {
14044            proto::language_server_log::LogType::Log(message_type) => Self::Log(
14045                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
14046                    LogLevel::Error => MessageType::ERROR,
14047                    LogLevel::Warning => MessageType::WARNING,
14048                    LogLevel::Info => MessageType::INFO,
14049                    LogLevel::Log => MessageType::LOG,
14050                },
14051            ),
14052            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
14053                verbose_info: trace_message.verbose_info,
14054            },
14055            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
14056                received: match rpc_message::Kind::from_i32(message.kind)
14057                    .unwrap_or(rpc_message::Kind::Received)
14058                {
14059                    rpc_message::Kind::Received => true,
14060                    rpc_message::Kind::Sent => false,
14061                },
14062            },
14063        }
14064    }
14065}
14066
14067pub struct WorkspaceRefreshTask {
14068    refresh_tx: mpsc::Sender<()>,
14069    progress_tx: mpsc::Sender<()>,
14070    #[allow(dead_code)]
14071    task: Task<()>,
14072}
14073
14074pub enum LanguageServerState {
14075    Starting {
14076        startup: Task<Option<Arc<LanguageServer>>>,
14077        /// List of language servers that will be added to the workspace once it's initialization completes.
14078        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
14079    },
14080
14081    Running {
14082        adapter: Arc<CachedLspAdapter>,
14083        server: Arc<LanguageServer>,
14084        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
14085        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
14086    },
14087}
14088
14089impl LanguageServerState {
14090    fn add_workspace_folder(&self, uri: Uri) {
14091        match self {
14092            LanguageServerState::Starting {
14093                pending_workspace_folders,
14094                ..
14095            } => {
14096                pending_workspace_folders.lock().insert(uri);
14097            }
14098            LanguageServerState::Running { server, .. } => {
14099                server.add_workspace_folder(uri);
14100            }
14101        }
14102    }
14103    fn _remove_workspace_folder(&self, uri: Uri) {
14104        match self {
14105            LanguageServerState::Starting {
14106                pending_workspace_folders,
14107                ..
14108            } => {
14109                pending_workspace_folders.lock().remove(&uri);
14110            }
14111            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
14112        }
14113    }
14114}
14115
14116impl std::fmt::Debug for LanguageServerState {
14117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14118        match self {
14119            LanguageServerState::Starting { .. } => {
14120                f.debug_struct("LanguageServerState::Starting").finish()
14121            }
14122            LanguageServerState::Running { .. } => {
14123                f.debug_struct("LanguageServerState::Running").finish()
14124            }
14125        }
14126    }
14127}
14128
14129#[derive(Clone, Debug, Serialize)]
14130pub struct LanguageServerProgress {
14131    pub is_disk_based_diagnostics_progress: bool,
14132    pub is_cancellable: bool,
14133    pub title: Option<String>,
14134    pub message: Option<String>,
14135    pub percentage: Option<usize>,
14136    #[serde(skip_serializing)]
14137    pub last_update_at: Instant,
14138}
14139
14140#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14141pub struct DiagnosticSummary {
14142    pub error_count: usize,
14143    pub warning_count: usize,
14144}
14145
14146impl DiagnosticSummary {
14147    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14148        let mut this = Self {
14149            error_count: 0,
14150            warning_count: 0,
14151        };
14152
14153        for entry in diagnostics {
14154            if entry.diagnostic.is_primary {
14155                match entry.diagnostic.severity {
14156                    DiagnosticSeverity::ERROR => this.error_count += 1,
14157                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14158                    _ => {}
14159                }
14160            }
14161        }
14162
14163        this
14164    }
14165
14166    pub fn is_empty(&self) -> bool {
14167        self.error_count == 0 && self.warning_count == 0
14168    }
14169
14170    pub fn to_proto(
14171        self,
14172        language_server_id: LanguageServerId,
14173        path: &RelPath,
14174    ) -> proto::DiagnosticSummary {
14175        proto::DiagnosticSummary {
14176            path: path.to_proto(),
14177            language_server_id: language_server_id.0 as u64,
14178            error_count: self.error_count as u32,
14179            warning_count: self.warning_count as u32,
14180        }
14181    }
14182}
14183
14184#[derive(Clone, Debug)]
14185pub enum CompletionDocumentation {
14186    /// There is no documentation for this completion.
14187    Undocumented,
14188    /// A single line of documentation.
14189    SingleLine(SharedString),
14190    /// Multiple lines of plain text documentation.
14191    MultiLinePlainText(SharedString),
14192    /// Markdown documentation.
14193    MultiLineMarkdown(SharedString),
14194    /// Both single line and multiple lines of plain text documentation.
14195    SingleLineAndMultiLinePlainText {
14196        single_line: SharedString,
14197        plain_text: Option<SharedString>,
14198    },
14199}
14200
14201impl CompletionDocumentation {
14202    #[cfg(any(test, feature = "test-support"))]
14203    pub fn text(&self) -> SharedString {
14204        match self {
14205            CompletionDocumentation::Undocumented => "".into(),
14206            CompletionDocumentation::SingleLine(s) => s.clone(),
14207            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14208            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14209            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14210                single_line.clone()
14211            }
14212        }
14213    }
14214}
14215
14216impl From<lsp::Documentation> for CompletionDocumentation {
14217    fn from(docs: lsp::Documentation) -> Self {
14218        match docs {
14219            lsp::Documentation::String(text) => {
14220                if text.lines().count() <= 1 {
14221                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14222                } else {
14223                    CompletionDocumentation::MultiLinePlainText(text.into())
14224                }
14225            }
14226
14227            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14228                lsp::MarkupKind::PlainText => {
14229                    if value.lines().count() <= 1 {
14230                        CompletionDocumentation::SingleLine(value.into())
14231                    } else {
14232                        CompletionDocumentation::MultiLinePlainText(value.into())
14233                    }
14234                }
14235
14236                lsp::MarkupKind::Markdown => {
14237                    CompletionDocumentation::MultiLineMarkdown(value.into())
14238                }
14239            },
14240        }
14241    }
14242}
14243
14244pub enum ResolvedHint {
14245    Resolved(InlayHint),
14246    Resolving(Shared<Task<()>>),
14247}
14248
14249pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14250    glob.components()
14251        .take_while(|component| match component {
14252            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14253            _ => true,
14254        })
14255        .collect()
14256}
14257
14258pub struct SshLspAdapter {
14259    name: LanguageServerName,
14260    binary: LanguageServerBinary,
14261    initialization_options: Option<String>,
14262    code_action_kinds: Option<Vec<CodeActionKind>>,
14263}
14264
14265impl SshLspAdapter {
14266    pub fn new(
14267        name: LanguageServerName,
14268        binary: LanguageServerBinary,
14269        initialization_options: Option<String>,
14270        code_action_kinds: Option<String>,
14271    ) -> Self {
14272        Self {
14273            name,
14274            binary,
14275            initialization_options,
14276            code_action_kinds: code_action_kinds
14277                .as_ref()
14278                .and_then(|c| serde_json::from_str(c).ok()),
14279        }
14280    }
14281}
14282
14283impl LspInstaller for SshLspAdapter {
14284    type BinaryVersion = ();
14285    async fn check_if_user_installed(
14286        &self,
14287        _: &dyn LspAdapterDelegate,
14288        _: Option<Toolchain>,
14289        _: &AsyncApp,
14290    ) -> Option<LanguageServerBinary> {
14291        Some(self.binary.clone())
14292    }
14293
14294    async fn cached_server_binary(
14295        &self,
14296        _: PathBuf,
14297        _: &dyn LspAdapterDelegate,
14298    ) -> Option<LanguageServerBinary> {
14299        None
14300    }
14301
14302    async fn fetch_latest_server_version(
14303        &self,
14304        _: &dyn LspAdapterDelegate,
14305        _: bool,
14306        _: &mut AsyncApp,
14307    ) -> Result<()> {
14308        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14309    }
14310
14311    async fn fetch_server_binary(
14312        &self,
14313        _: (),
14314        _: PathBuf,
14315        _: &dyn LspAdapterDelegate,
14316    ) -> Result<LanguageServerBinary> {
14317        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14318    }
14319}
14320
14321#[async_trait(?Send)]
14322impl LspAdapter for SshLspAdapter {
14323    fn name(&self) -> LanguageServerName {
14324        self.name.clone()
14325    }
14326
14327    async fn initialization_options(
14328        self: Arc<Self>,
14329        _: &Arc<dyn LspAdapterDelegate>,
14330        _: &mut AsyncApp,
14331    ) -> Result<Option<serde_json::Value>> {
14332        let Some(options) = &self.initialization_options else {
14333            return Ok(None);
14334        };
14335        let result = serde_json::from_str(options)?;
14336        Ok(result)
14337    }
14338
14339    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14340        self.code_action_kinds.clone()
14341    }
14342}
14343
14344pub fn language_server_settings<'a>(
14345    delegate: &'a dyn LspAdapterDelegate,
14346    language: &LanguageServerName,
14347    cx: &'a App,
14348) -> Option<&'a LspSettings> {
14349    language_server_settings_for(
14350        SettingsLocation {
14351            worktree_id: delegate.worktree_id(),
14352            path: RelPath::empty(),
14353        },
14354        language,
14355        cx,
14356    )
14357}
14358
14359pub fn language_server_settings_for<'a>(
14360    location: SettingsLocation<'a>,
14361    language: &LanguageServerName,
14362    cx: &'a App,
14363) -> Option<&'a LspSettings> {
14364    ProjectSettings::get(Some(location), cx).lsp.get(language)
14365}
14366
14367pub struct LocalLspAdapterDelegate {
14368    lsp_store: WeakEntity<LspStore>,
14369    worktree: worktree::Snapshot,
14370    fs: Arc<dyn Fs>,
14371    http_client: Arc<dyn HttpClient>,
14372    language_registry: Arc<LanguageRegistry>,
14373    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14374}
14375
14376impl LocalLspAdapterDelegate {
14377    pub fn new(
14378        language_registry: Arc<LanguageRegistry>,
14379        environment: &Entity<ProjectEnvironment>,
14380        lsp_store: WeakEntity<LspStore>,
14381        worktree: &Entity<Worktree>,
14382        http_client: Arc<dyn HttpClient>,
14383        fs: Arc<dyn Fs>,
14384        cx: &mut App,
14385    ) -> Arc<Self> {
14386        let load_shell_env_task =
14387            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14388
14389        Arc::new(Self {
14390            lsp_store,
14391            worktree: worktree.read(cx).snapshot(),
14392            fs,
14393            http_client,
14394            language_registry,
14395            load_shell_env_task,
14396        })
14397    }
14398
14399    pub fn from_local_lsp(
14400        local: &LocalLspStore,
14401        worktree: &Entity<Worktree>,
14402        cx: &mut App,
14403    ) -> Arc<Self> {
14404        Self::new(
14405            local.languages.clone(),
14406            &local.environment,
14407            local.weak.clone(),
14408            worktree,
14409            local.http_client.clone(),
14410            local.fs.clone(),
14411            cx,
14412        )
14413    }
14414}
14415
14416#[async_trait]
14417impl LspAdapterDelegate for LocalLspAdapterDelegate {
14418    fn show_notification(&self, message: &str, cx: &mut App) {
14419        self.lsp_store
14420            .update(cx, |_, cx| {
14421                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14422            })
14423            .ok();
14424    }
14425
14426    fn http_client(&self) -> Arc<dyn HttpClient> {
14427        self.http_client.clone()
14428    }
14429
14430    fn worktree_id(&self) -> WorktreeId {
14431        self.worktree.id()
14432    }
14433
14434    fn worktree_root_path(&self) -> &Path {
14435        self.worktree.abs_path().as_ref()
14436    }
14437
14438    fn resolve_relative_path(&self, path: PathBuf) -> PathBuf {
14439        self.worktree.resolve_relative_path(path)
14440    }
14441
14442    async fn shell_env(&self) -> HashMap<String, String> {
14443        let task = self.load_shell_env_task.clone();
14444        task.await.unwrap_or_default()
14445    }
14446
14447    async fn npm_package_installed_version(
14448        &self,
14449        package_name: &str,
14450    ) -> Result<Option<(PathBuf, Version)>> {
14451        let local_package_directory = self.worktree_root_path();
14452        let node_modules_directory = local_package_directory.join("node_modules");
14453
14454        if let Some(version) =
14455            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14456        {
14457            return Ok(Some((node_modules_directory, version)));
14458        }
14459        let Some(npm) = self.which("npm".as_ref()).await else {
14460            log::warn!(
14461                "Failed to find npm executable for {:?}",
14462                local_package_directory
14463            );
14464            return Ok(None);
14465        };
14466
14467        let env = self.shell_env().await;
14468        let output = util::command::new_command(&npm)
14469            .args(["root", "-g"])
14470            .envs(env)
14471            .current_dir(local_package_directory)
14472            .output()
14473            .await?;
14474        let global_node_modules =
14475            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14476
14477        if let Some(version) =
14478            read_package_installed_version(global_node_modules.clone(), package_name).await?
14479        {
14480            return Ok(Some((global_node_modules, version)));
14481        }
14482        return Ok(None);
14483    }
14484
14485    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14486        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14487        if self.fs.is_file(&worktree_abs_path).await {
14488            worktree_abs_path.pop();
14489        }
14490
14491        let env = self.shell_env().await;
14492
14493        let shell_path = env.get("PATH").cloned();
14494
14495        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14496    }
14497
14498    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14499        let mut working_dir = self.worktree_root_path().to_path_buf();
14500        if self.fs.is_file(&working_dir).await {
14501            working_dir.pop();
14502        }
14503        let output = util::command::new_command(&command.path)
14504            .args(command.arguments)
14505            .envs(command.env.clone().unwrap_or_default())
14506            .current_dir(working_dir)
14507            .output()
14508            .await?;
14509
14510        anyhow::ensure!(
14511            output.status.success(),
14512            "{}, stdout: {:?}, stderr: {:?}",
14513            output.status,
14514            String::from_utf8_lossy(&output.stdout),
14515            String::from_utf8_lossy(&output.stderr)
14516        );
14517        Ok(())
14518    }
14519
14520    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14521        self.language_registry
14522            .update_lsp_binary_status(server_name, status);
14523    }
14524
14525    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14526        self.language_registry
14527            .all_lsp_adapters()
14528            .into_iter()
14529            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14530            .collect()
14531    }
14532
14533    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14534        let dir = self.language_registry.language_server_download_dir(name)?;
14535
14536        if !dir.exists() {
14537            smol::fs::create_dir_all(&dir)
14538                .await
14539                .context("failed to create container directory")
14540                .log_err()?;
14541        }
14542
14543        Some(dir)
14544    }
14545
14546    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14547        let entry = self
14548            .worktree
14549            .entry_for_path(path)
14550            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14551        let abs_path = self.worktree.absolutize(&entry.path);
14552        self.fs.load(&abs_path).await
14553    }
14554}
14555
14556async fn populate_labels_for_symbols(
14557    symbols: Vec<CoreSymbol>,
14558    language_registry: &Arc<LanguageRegistry>,
14559    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14560    output: &mut Vec<Symbol>,
14561) {
14562    #[allow(clippy::mutable_key_type)]
14563    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14564
14565    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14566    for symbol in symbols {
14567        let Some(file_name) = symbol.path.file_name() else {
14568            continue;
14569        };
14570        let language = language_registry
14571            .load_language_for_file_path(Path::new(file_name))
14572            .await
14573            .ok()
14574            .or_else(|| {
14575                unknown_paths.insert(file_name.into());
14576                None
14577            });
14578        symbols_by_language
14579            .entry(language)
14580            .or_default()
14581            .push(symbol);
14582    }
14583
14584    for unknown_path in unknown_paths {
14585        log::info!("no language found for symbol in file {unknown_path:?}");
14586    }
14587
14588    let mut label_params = Vec::new();
14589    for (language, mut symbols) in symbols_by_language {
14590        label_params.clear();
14591        label_params.extend(symbols.iter_mut().map(|symbol| language::Symbol {
14592            name: mem::take(&mut symbol.name),
14593            kind: symbol.kind,
14594            container_name: symbol.container_name.take(),
14595        }));
14596
14597        let mut labels = Vec::new();
14598        if let Some(language) = language {
14599            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14600                language_registry
14601                    .lsp_adapters(&language.name())
14602                    .first()
14603                    .cloned()
14604            });
14605            if let Some(lsp_adapter) = lsp_adapter {
14606                labels = lsp_adapter
14607                    .labels_for_symbols(&label_params, &language)
14608                    .await
14609                    .log_err()
14610                    .unwrap_or_default();
14611            }
14612        }
14613
14614        for (
14615            (
14616                symbol,
14617                language::Symbol {
14618                    name,
14619                    container_name,
14620                    ..
14621                },
14622            ),
14623            label,
14624        ) in symbols
14625            .into_iter()
14626            .zip(label_params.drain(..))
14627            .zip(labels.into_iter().chain(iter::repeat(None)))
14628        {
14629            output.push(Symbol {
14630                language_server_name: symbol.language_server_name,
14631                source_worktree_id: symbol.source_worktree_id,
14632                source_language_server_id: symbol.source_language_server_id,
14633                path: symbol.path,
14634                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14635                name,
14636                kind: symbol.kind,
14637                range: symbol.range,
14638                container_name,
14639            });
14640        }
14641    }
14642}
14643
14644pub(crate) fn collapse_newlines(text: &str, separator: &str) -> String {
14645    text.lines()
14646        .map(|line| line.trim())
14647        .filter(|line| !line.is_empty())
14648        .join(separator)
14649}
14650
14651fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14652    match server.capabilities().text_document_sync.as_ref()? {
14653        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14654            // Server wants didSave but didn't specify includeText.
14655            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14656            // Server doesn't want didSave at all.
14657            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14658            // Server provided SaveOptions.
14659            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14660                Some(save_options.include_text.unwrap_or(false))
14661            }
14662        },
14663        // We do not have any save info. Kind affects didChange only.
14664        lsp::TextDocumentSyncCapability::Kind(_) => None,
14665    }
14666}
14667
14668/// Completion items are displayed in a `UniformList`.
14669/// Usually, those items are single-line strings, but in LSP responses,
14670/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14671/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14672/// 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,
14673/// breaking the completions menu presentation.
14674///
14675/// 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.
14676pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14677    let mut new_text = String::with_capacity(label.text.len());
14678    let mut offset_map = vec![0; label.text.len() + 1];
14679    let mut last_char_was_space = false;
14680    let mut new_idx = 0;
14681    let chars = label.text.char_indices().fuse();
14682    let mut newlines_removed = false;
14683
14684    for (idx, c) in chars {
14685        offset_map[idx] = new_idx;
14686
14687        match c {
14688            '\n' if last_char_was_space => {
14689                newlines_removed = true;
14690            }
14691            '\t' | ' ' if last_char_was_space => {}
14692            '\n' if !last_char_was_space => {
14693                new_text.push(' ');
14694                new_idx += 1;
14695                last_char_was_space = true;
14696                newlines_removed = true;
14697            }
14698            ' ' | '\t' => {
14699                new_text.push(' ');
14700                new_idx += 1;
14701                last_char_was_space = true;
14702            }
14703            _ => {
14704                new_text.push(c);
14705                new_idx += c.len_utf8();
14706                last_char_was_space = false;
14707            }
14708        }
14709    }
14710    offset_map[label.text.len()] = new_idx;
14711
14712    // Only modify the label if newlines were removed.
14713    if !newlines_removed {
14714        return;
14715    }
14716
14717    let last_index = new_idx;
14718    let mut run_ranges_errors = Vec::new();
14719    label.runs.retain_mut(|(range, _)| {
14720        match offset_map.get(range.start) {
14721            Some(&start) => range.start = start,
14722            None => {
14723                run_ranges_errors.push(range.clone());
14724                return false;
14725            }
14726        }
14727
14728        match offset_map.get(range.end) {
14729            Some(&end) => range.end = end,
14730            None => {
14731                run_ranges_errors.push(range.clone());
14732                range.end = last_index;
14733            }
14734        }
14735        true
14736    });
14737    if !run_ranges_errors.is_empty() {
14738        log::error!(
14739            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14740            label.text
14741        );
14742    }
14743
14744    let mut wrong_filter_range = None;
14745    if label.filter_range == (0..label.text.len()) {
14746        label.filter_range = 0..new_text.len();
14747    } else {
14748        let mut original_filter_range = Some(label.filter_range.clone());
14749        match offset_map.get(label.filter_range.start) {
14750            Some(&start) => label.filter_range.start = start,
14751            None => {
14752                wrong_filter_range = original_filter_range.take();
14753                label.filter_range.start = last_index;
14754            }
14755        }
14756
14757        match offset_map.get(label.filter_range.end) {
14758            Some(&end) => label.filter_range.end = end,
14759            None => {
14760                wrong_filter_range = original_filter_range.take();
14761                label.filter_range.end = last_index;
14762            }
14763        }
14764    }
14765    if let Some(wrong_filter_range) = wrong_filter_range {
14766        log::error!(
14767            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14768            label.text
14769        );
14770    }
14771
14772    label.text = new_text;
14773}
14774
14775/// Apply edits to the buffer that will become part of the formatting transaction.
14776/// Fails if the buffer has been edited since the start of that transaction.
14777fn extend_formatting_transaction(
14778    buffer: &FormattableBuffer,
14779    formatting_transaction_id: text::TransactionId,
14780    cx: &mut AsyncApp,
14781    operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
14782) -> anyhow::Result<()> {
14783    buffer.handle.update(cx, |buffer, cx| {
14784        let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
14785        if last_transaction_id != Some(formatting_transaction_id) {
14786            anyhow::bail!("Buffer edited while formatting. Aborting")
14787        }
14788        buffer.start_transaction();
14789        operation(buffer, cx);
14790        if let Some(transaction_id) = buffer.end_transaction(cx) {
14791            buffer.merge_transactions(transaction_id, formatting_transaction_id);
14792        }
14793        Ok(())
14794    })
14795}