lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17
   18use crate::{
   19    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   20    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction,
   21    LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   22    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   23    buffer_store::{BufferStore, BufferStoreEvent},
   24    environment::ProjectEnvironment,
   25    lsp_command::{self, *},
   26    lsp_store::{
   27        self,
   28        log_store::{GlobalLogStore, LanguageServerKind},
   29    },
   30    manifest_tree::{
   31        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   32        ManifestTree,
   33    },
   34    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   35    project_settings::{LspSettings, ProjectSettings},
   36    relativize_path, resolve_path,
   37    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   38    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   39    yarn::YarnPathStore,
   40};
   41use anyhow::{Context as _, Result, anyhow};
   42use async_trait::async_trait;
   43use client::{TypedEnvelope, proto};
   44use clock::Global;
   45use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   46use futures::{
   47    AsyncWriteExt, Future, FutureExt, StreamExt,
   48    future::{Either, Shared, join_all, pending, select},
   49    select, select_biased,
   50    stream::FuturesUnordered,
   51};
   52use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   53use gpui::{
   54    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   55    WeakEntity,
   56};
   57use http_client::HttpClient;
   58use itertools::Itertools as _;
   59use language::{
   60    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   61    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   62    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, ManifestDelegate, ManifestName,
   63    Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPoint, ToPointUtf16, Toolchain, Transaction,
   64    Unclipped,
   65    language_settings::{
   66        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   67    },
   68    point_to_lsp,
   69    proto::{
   70        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   71        serialize_lsp_edit, serialize_version,
   72    },
   73    range_from_lsp, range_to_lsp,
   74};
   75use lsp::{
   76    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   77    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   78    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   79    LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
   80    LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
   81    MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   82    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   83    WorkspaceFolder, notification::DidRenameFiles,
   84};
   85use node_runtime::read_package_installed_version;
   86use parking_lot::Mutex;
   87use postage::{mpsc, sink::Sink, stream::Stream, watch};
   88use rand::prelude::*;
   89use rpc::{
   90    AnyProtoClient,
   91    proto::{FromProto, LspRequestId, LspRequestMessage as _, ToProto},
   92};
   93use serde::Serialize;
   94use settings::{Settings, SettingsLocation, SettingsStore};
   95use sha2::{Digest, Sha256};
   96use smol::channel::Sender;
   97use snippet::Snippet;
   98use std::{
   99    any::{Any, TypeId},
  100    borrow::Cow,
  101    cell::RefCell,
  102    cmp::{Ordering, Reverse},
  103    convert::TryInto,
  104    ffi::OsStr,
  105    future::ready,
  106    iter, mem,
  107    ops::{ControlFlow, Range},
  108    path::{self, Path, PathBuf},
  109    pin::pin,
  110    rc::Rc,
  111    sync::Arc,
  112    time::{Duration, Instant},
  113};
  114use sum_tree::Dimensions;
  115use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  116
  117use util::{
  118    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  119    paths::{PathExt, SanitizedPath},
  120    post_inc,
  121};
  122
  123pub use fs::*;
  124pub use language::Location;
  125#[cfg(any(test, feature = "test-support"))]
  126pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  127pub use worktree::{
  128    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  129    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  130};
  131
  132const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  133pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  134
  135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  136pub enum FormatTrigger {
  137    Save,
  138    Manual,
  139}
  140
  141pub enum LspFormatTarget {
  142    Buffers,
  143    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  144}
  145
  146pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  147
  148impl FormatTrigger {
  149    fn from_proto(value: i32) -> FormatTrigger {
  150        match value {
  151            0 => FormatTrigger::Save,
  152            1 => FormatTrigger::Manual,
  153            _ => FormatTrigger::Save,
  154        }
  155    }
  156}
  157
  158#[derive(Clone)]
  159struct UnifiedLanguageServer {
  160    id: LanguageServerId,
  161    project_roots: HashSet<Arc<Path>>,
  162}
  163
  164#[derive(Clone, Hash, PartialEq, Eq)]
  165struct LanguageServerSeed {
  166    worktree_id: WorktreeId,
  167    name: LanguageServerName,
  168    toolchain: Option<Toolchain>,
  169    settings: Arc<LspSettings>,
  170}
  171
  172#[derive(Debug)]
  173pub struct DocumentDiagnosticsUpdate<'a, D> {
  174    pub diagnostics: D,
  175    pub result_id: Option<String>,
  176    pub server_id: LanguageServerId,
  177    pub disk_based_sources: Cow<'a, [String]>,
  178}
  179
  180pub struct DocumentDiagnostics {
  181    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  182    document_abs_path: PathBuf,
  183    version: Option<i32>,
  184}
  185
  186pub struct LocalLspStore {
  187    weak: WeakEntity<LspStore>,
  188    worktree_store: Entity<WorktreeStore>,
  189    toolchain_store: Entity<LocalToolchainStore>,
  190    http_client: Arc<dyn HttpClient>,
  191    environment: Entity<ProjectEnvironment>,
  192    fs: Arc<dyn Fs>,
  193    languages: Arc<LanguageRegistry>,
  194    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  195    yarn: Entity<YarnPathStore>,
  196    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  197    buffers_being_formatted: HashSet<BufferId>,
  198    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  199    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  200    watched_manifest_filenames: HashSet<ManifestName>,
  201    language_server_paths_watched_for_rename:
  202        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  203    language_server_watcher_registrations:
  204        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  205    supplementary_language_servers:
  206        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  207    prettier_store: Entity<PrettierStore>,
  208    next_diagnostic_group_id: usize,
  209    diagnostics: HashMap<
  210        WorktreeId,
  211        HashMap<
  212            Arc<Path>,
  213            Vec<(
  214                LanguageServerId,
  215                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  216            )>,
  217        >,
  218    >,
  219    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  220    _subscription: gpui::Subscription,
  221    lsp_tree: LanguageServerTree,
  222    registered_buffers: HashMap<BufferId, usize>,
  223    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  224    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  225}
  226
  227impl LocalLspStore {
  228    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  229    pub fn running_language_server_for_id(
  230        &self,
  231        id: LanguageServerId,
  232    ) -> Option<&Arc<LanguageServer>> {
  233        let language_server_state = self.language_servers.get(&id)?;
  234
  235        match language_server_state {
  236            LanguageServerState::Running { server, .. } => Some(server),
  237            LanguageServerState::Starting { .. } => None,
  238        }
  239    }
  240
  241    fn get_or_insert_language_server(
  242        &mut self,
  243        worktree_handle: &Entity<Worktree>,
  244        delegate: Arc<LocalLspAdapterDelegate>,
  245        disposition: &Arc<LaunchDisposition>,
  246        language_name: &LanguageName,
  247        cx: &mut App,
  248    ) -> LanguageServerId {
  249        let key = LanguageServerSeed {
  250            worktree_id: worktree_handle.read(cx).id(),
  251            name: disposition.server_name.clone(),
  252            settings: disposition.settings.clone(),
  253            toolchain: disposition.toolchain.clone(),
  254        };
  255        if let Some(state) = self.language_server_ids.get_mut(&key) {
  256            state.project_roots.insert(disposition.path.path.clone());
  257            state.id
  258        } else {
  259            let adapter = self
  260                .languages
  261                .lsp_adapters(language_name)
  262                .into_iter()
  263                .find(|adapter| adapter.name() == disposition.server_name)
  264                .expect("To find LSP adapter");
  265            let new_language_server_id = self.start_language_server(
  266                worktree_handle,
  267                delegate,
  268                adapter,
  269                disposition.settings.clone(),
  270                key.clone(),
  271                cx,
  272            );
  273            if let Some(state) = self.language_server_ids.get_mut(&key) {
  274                state.project_roots.insert(disposition.path.path.clone());
  275            } else {
  276                debug_assert!(
  277                    false,
  278                    "Expected `start_language_server` to ensure that `key` exists in a map"
  279                );
  280            }
  281            new_language_server_id
  282        }
  283    }
  284
  285    fn start_language_server(
  286        &mut self,
  287        worktree_handle: &Entity<Worktree>,
  288        delegate: Arc<LocalLspAdapterDelegate>,
  289        adapter: Arc<CachedLspAdapter>,
  290        settings: Arc<LspSettings>,
  291        key: LanguageServerSeed,
  292        cx: &mut App,
  293    ) -> LanguageServerId {
  294        let worktree = worktree_handle.read(cx);
  295
  296        let root_path = worktree.abs_path();
  297        let toolchain = key.toolchain.clone();
  298        let override_options = settings.initialization_options.clone();
  299
  300        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  301
  302        let server_id = self.languages.next_language_server_id();
  303        log::trace!(
  304            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  305            adapter.name.0
  306        );
  307
  308        let binary = self.get_language_server_binary(
  309            adapter.clone(),
  310            settings,
  311            toolchain.clone(),
  312            delegate.clone(),
  313            true,
  314            cx,
  315        );
  316        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  317
  318        let pending_server = cx.spawn({
  319            let adapter = adapter.clone();
  320            let server_name = adapter.name.clone();
  321            let stderr_capture = stderr_capture.clone();
  322            #[cfg(any(test, feature = "test-support"))]
  323            let lsp_store = self.weak.clone();
  324            let pending_workspace_folders = pending_workspace_folders.clone();
  325            async move |cx| {
  326                let binary = binary.await?;
  327                #[cfg(any(test, feature = "test-support"))]
  328                if let Some(server) = lsp_store
  329                    .update(&mut cx.clone(), |this, cx| {
  330                        this.languages.create_fake_language_server(
  331                            server_id,
  332                            &server_name,
  333                            binary.clone(),
  334                            &mut cx.to_async(),
  335                        )
  336                    })
  337                    .ok()
  338                    .flatten()
  339                {
  340                    return Ok(server);
  341                }
  342
  343                let code_action_kinds = adapter.code_action_kinds();
  344                lsp::LanguageServer::new(
  345                    stderr_capture,
  346                    server_id,
  347                    server_name,
  348                    binary,
  349                    &root_path,
  350                    code_action_kinds,
  351                    Some(pending_workspace_folders),
  352                    cx,
  353                )
  354            }
  355        });
  356
  357        let startup = {
  358            let server_name = adapter.name.0.clone();
  359            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  360            let key = key.clone();
  361            let adapter = adapter.clone();
  362            let lsp_store = self.weak.clone();
  363            let pending_workspace_folders = pending_workspace_folders.clone();
  364
  365            let pull_diagnostics = ProjectSettings::get_global(cx)
  366                .diagnostics
  367                .lsp_pull_diagnostics
  368                .enabled;
  369            cx.spawn(async move |cx| {
  370                let result = async {
  371                    let language_server = pending_server.await?;
  372
  373                    let workspace_config = Self::workspace_configuration_for_adapter(
  374                        adapter.adapter.clone(),
  375                        &delegate,
  376                        toolchain,
  377                        cx,
  378                    )
  379                    .await?;
  380
  381                    let mut initialization_options = Self::initialization_options_for_adapter(
  382                        adapter.adapter.clone(),
  383                        &delegate,
  384                    )
  385                    .await?;
  386
  387                    match (&mut initialization_options, override_options) {
  388                        (Some(initialization_options), Some(override_options)) => {
  389                            merge_json_value_into(override_options, initialization_options);
  390                        }
  391                        (None, override_options) => initialization_options = override_options,
  392                        _ => {}
  393                    }
  394
  395                    let initialization_params = cx.update(|cx| {
  396                        let mut params =
  397                            language_server.default_initialize_params(pull_diagnostics, cx);
  398                        params.initialization_options = initialization_options;
  399                        adapter.adapter.prepare_initialize_params(params, cx)
  400                    })??;
  401
  402                    Self::setup_lsp_messages(
  403                        lsp_store.clone(),
  404                        &language_server,
  405                        delegate.clone(),
  406                        adapter.clone(),
  407                    );
  408
  409                    let did_change_configuration_params =
  410                        Arc::new(lsp::DidChangeConfigurationParams {
  411                            settings: workspace_config,
  412                        });
  413                    let language_server = cx
  414                        .update(|cx| {
  415                            language_server.initialize(
  416                                initialization_params,
  417                                did_change_configuration_params.clone(),
  418                                cx,
  419                            )
  420                        })?
  421                        .await
  422                        .inspect_err(|_| {
  423                            if let Some(lsp_store) = lsp_store.upgrade() {
  424                                lsp_store
  425                                    .update(cx, |lsp_store, cx| {
  426                                        lsp_store.cleanup_lsp_data(server_id);
  427                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  428                                    })
  429                                    .ok();
  430                            }
  431                        })?;
  432
  433                    language_server
  434                        .notify::<lsp::notification::DidChangeConfiguration>(
  435                            &did_change_configuration_params,
  436                        )
  437                        .ok();
  438
  439                    anyhow::Ok(language_server)
  440                }
  441                .await;
  442
  443                match result {
  444                    Ok(server) => {
  445                        lsp_store
  446                            .update(cx, |lsp_store, cx| {
  447                                lsp_store.insert_newly_running_language_server(
  448                                    adapter,
  449                                    server.clone(),
  450                                    server_id,
  451                                    key,
  452                                    pending_workspace_folders,
  453                                    cx,
  454                                );
  455                            })
  456                            .ok();
  457                        stderr_capture.lock().take();
  458                        Some(server)
  459                    }
  460
  461                    Err(err) => {
  462                        let log = stderr_capture.lock().take().unwrap_or_default();
  463                        delegate.update_status(
  464                            adapter.name(),
  465                            BinaryStatus::Failed {
  466                                error: if log.is_empty() {
  467                                    format!("{err:#}")
  468                                } else {
  469                                    format!("{err:#}\n-- stderr --\n{log}")
  470                                },
  471                            },
  472                        );
  473                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  474                        if !log.is_empty() {
  475                            log::error!("server stderr: {log}");
  476                        }
  477                        None
  478                    }
  479                }
  480            })
  481        };
  482        let state = LanguageServerState::Starting {
  483            startup,
  484            pending_workspace_folders,
  485        };
  486
  487        self.languages
  488            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  489
  490        self.language_servers.insert(server_id, state);
  491        self.language_server_ids
  492            .entry(key)
  493            .or_insert(UnifiedLanguageServer {
  494                id: server_id,
  495                project_roots: Default::default(),
  496            });
  497        server_id
  498    }
  499
  500    fn get_language_server_binary(
  501        &self,
  502        adapter: Arc<CachedLspAdapter>,
  503        settings: Arc<LspSettings>,
  504        toolchain: Option<Toolchain>,
  505        delegate: Arc<dyn LspAdapterDelegate>,
  506        allow_binary_download: bool,
  507        cx: &mut App,
  508    ) -> Task<Result<LanguageServerBinary>> {
  509        if let Some(settings) = settings.binary.as_ref()
  510            && settings.path.is_some()
  511        {
  512            let settings = settings.clone();
  513
  514            return cx.background_spawn(async move {
  515                let mut env = delegate.shell_env().await;
  516                env.extend(settings.env.unwrap_or_default());
  517
  518                Ok(LanguageServerBinary {
  519                    path: PathBuf::from(&settings.path.unwrap()),
  520                    env: Some(env),
  521                    arguments: settings
  522                        .arguments
  523                        .unwrap_or_default()
  524                        .iter()
  525                        .map(Into::into)
  526                        .collect(),
  527                })
  528            });
  529        }
  530        let lsp_binary_options = LanguageServerBinaryOptions {
  531            allow_path_lookup: !settings
  532                .binary
  533                .as_ref()
  534                .and_then(|b| b.ignore_system_version)
  535                .unwrap_or_default(),
  536            allow_binary_download,
  537        };
  538
  539        cx.spawn(async move |cx| {
  540            let binary_result = adapter
  541                .clone()
  542                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  543                .await;
  544
  545            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  546
  547            let mut binary = binary_result?;
  548            let mut shell_env = delegate.shell_env().await;
  549
  550            shell_env.extend(binary.env.unwrap_or_default());
  551
  552            if let Some(settings) = settings.binary.as_ref() {
  553                if let Some(arguments) = &settings.arguments {
  554                    binary.arguments = arguments.iter().map(Into::into).collect();
  555                }
  556                if let Some(env) = &settings.env {
  557                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  558                }
  559            }
  560
  561            binary.env = Some(shell_env);
  562            Ok(binary)
  563        })
  564    }
  565
  566    fn setup_lsp_messages(
  567        this: WeakEntity<LspStore>,
  568
  569        language_server: &LanguageServer,
  570        delegate: Arc<dyn LspAdapterDelegate>,
  571        adapter: Arc<CachedLspAdapter>,
  572    ) {
  573        let name = language_server.name();
  574        let server_id = language_server.server_id();
  575        language_server
  576            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  577                let adapter = adapter.clone();
  578                let this = this.clone();
  579                move |mut params, cx| {
  580                    let adapter = adapter.clone();
  581                    if let Some(this) = this.upgrade() {
  582                        this.update(cx, |this, cx| {
  583                            {
  584                                let buffer = params
  585                                    .uri
  586                                    .to_file_path()
  587                                    .map(|file_path| this.get_buffer(&file_path, cx))
  588                                    .ok()
  589                                    .flatten();
  590                                adapter.process_diagnostics(&mut params, server_id, buffer);
  591                            }
  592
  593                            this.merge_lsp_diagnostics(
  594                                DiagnosticSourceKind::Pushed,
  595                                vec![DocumentDiagnosticsUpdate {
  596                                    server_id,
  597                                    diagnostics: params,
  598                                    result_id: None,
  599                                    disk_based_sources: Cow::Borrowed(
  600                                        &adapter.disk_based_diagnostic_sources,
  601                                    ),
  602                                }],
  603                                |_, diagnostic, cx| match diagnostic.source_kind {
  604                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  605                                        adapter.retain_old_diagnostic(diagnostic, cx)
  606                                    }
  607                                    DiagnosticSourceKind::Pulled => true,
  608                                },
  609                                cx,
  610                            )
  611                            .log_err();
  612                        })
  613                        .ok();
  614                    }
  615                }
  616            })
  617            .detach();
  618        language_server
  619            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  620                let adapter = adapter.adapter.clone();
  621                let delegate = delegate.clone();
  622                let this = this.clone();
  623
  624                move |params, cx| {
  625                    let adapter = adapter.clone();
  626                    let delegate = delegate.clone();
  627                    let this = this.clone();
  628                    let mut cx = cx.clone();
  629                    async move {
  630                        let toolchain_for_id = this
  631                            .update(&mut cx, |this, _| {
  632                                this.as_local()?.language_server_ids.iter().find_map(
  633                                    |(seed, value)| {
  634                                        (value.id == server_id).then(|| seed.toolchain.clone())
  635                                    },
  636                                )
  637                            })?
  638                            .context("Expected the LSP store to be in a local mode")?;
  639                        let workspace_config = Self::workspace_configuration_for_adapter(
  640                            adapter.clone(),
  641                            &delegate,
  642                            toolchain_for_id,
  643                            &mut cx,
  644                        )
  645                        .await?;
  646
  647                        Ok(params
  648                            .items
  649                            .into_iter()
  650                            .map(|item| {
  651                                if let Some(section) = &item.section {
  652                                    workspace_config
  653                                        .get(section)
  654                                        .cloned()
  655                                        .unwrap_or(serde_json::Value::Null)
  656                                } else {
  657                                    workspace_config.clone()
  658                                }
  659                            })
  660                            .collect())
  661                    }
  662                }
  663            })
  664            .detach();
  665
  666        language_server
  667            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  668                let this = this.clone();
  669                move |_, cx| {
  670                    let this = this.clone();
  671                    let cx = cx.clone();
  672                    async move {
  673                        let Some(server) =
  674                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  675                        else {
  676                            return Ok(None);
  677                        };
  678                        let root = server.workspace_folders();
  679                        Ok(Some(
  680                            root.into_iter()
  681                                .map(|uri| WorkspaceFolder {
  682                                    uri,
  683                                    name: Default::default(),
  684                                })
  685                                .collect(),
  686                        ))
  687                    }
  688                }
  689            })
  690            .detach();
  691        // Even though we don't have handling for these requests, respond to them to
  692        // avoid stalling any language server like `gopls` which waits for a response
  693        // to these requests when initializing.
  694        language_server
  695            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  696                let this = this.clone();
  697                move |params, cx| {
  698                    let this = this.clone();
  699                    let mut cx = cx.clone();
  700                    async move {
  701                        this.update(&mut cx, |this, _| {
  702                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  703                                && let lsp::NumberOrString::String(token) = params.token
  704                            {
  705                                status.progress_tokens.insert(token);
  706                            }
  707                        })?;
  708
  709                        Ok(())
  710                    }
  711                }
  712            })
  713            .detach();
  714
  715        language_server
  716            .on_request::<lsp::request::RegisterCapability, _, _>({
  717                let lsp_store = this.clone();
  718                move |params, cx| {
  719                    let lsp_store = lsp_store.clone();
  720                    let mut cx = cx.clone();
  721                    async move {
  722                        lsp_store
  723                            .update(&mut cx, |lsp_store, cx| {
  724                                if lsp_store.as_local().is_some() {
  725                                    match lsp_store
  726                                        .register_server_capabilities(server_id, params, cx)
  727                                    {
  728                                        Ok(()) => {}
  729                                        Err(e) => {
  730                                            log::error!(
  731                                                "Failed to register server capabilities: {e:#}"
  732                                            );
  733                                        }
  734                                    };
  735                                }
  736                            })
  737                            .ok();
  738                        Ok(())
  739                    }
  740                }
  741            })
  742            .detach();
  743
  744        language_server
  745            .on_request::<lsp::request::UnregisterCapability, _, _>({
  746                let lsp_store = this.clone();
  747                move |params, cx| {
  748                    let lsp_store = lsp_store.clone();
  749                    let mut cx = cx.clone();
  750                    async move {
  751                        lsp_store
  752                            .update(&mut cx, |lsp_store, cx| {
  753                                if lsp_store.as_local().is_some() {
  754                                    match lsp_store
  755                                        .unregister_server_capabilities(server_id, params, cx)
  756                                    {
  757                                        Ok(()) => {}
  758                                        Err(e) => {
  759                                            log::error!(
  760                                                "Failed to unregister server capabilities: {e:#}"
  761                                            );
  762                                        }
  763                                    }
  764                                }
  765                            })
  766                            .ok();
  767                        Ok(())
  768                    }
  769                }
  770            })
  771            .detach();
  772
  773        language_server
  774            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  775                let this = this.clone();
  776                move |params, cx| {
  777                    let mut cx = cx.clone();
  778                    let this = this.clone();
  779                    async move {
  780                        LocalLspStore::on_lsp_workspace_edit(
  781                            this.clone(),
  782                            params,
  783                            server_id,
  784                            &mut cx,
  785                        )
  786                        .await
  787                    }
  788                }
  789            })
  790            .detach();
  791
  792        language_server
  793            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  794                let this = this.clone();
  795                move |(), cx| {
  796                    let this = this.clone();
  797                    let mut cx = cx.clone();
  798                    async move {
  799                        this.update(&mut cx, |this, cx| {
  800                            cx.emit(LspStoreEvent::RefreshInlayHints);
  801                            this.downstream_client.as_ref().map(|(client, project_id)| {
  802                                client.send(proto::RefreshInlayHints {
  803                                    project_id: *project_id,
  804                                })
  805                            })
  806                        })?
  807                        .transpose()?;
  808                        Ok(())
  809                    }
  810                }
  811            })
  812            .detach();
  813
  814        language_server
  815            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  816                let this = this.clone();
  817                move |(), cx| {
  818                    let this = this.clone();
  819                    let mut cx = cx.clone();
  820                    async move {
  821                        this.update(&mut cx, |this, cx| {
  822                            cx.emit(LspStoreEvent::RefreshCodeLens);
  823                            this.downstream_client.as_ref().map(|(client, project_id)| {
  824                                client.send(proto::RefreshCodeLens {
  825                                    project_id: *project_id,
  826                                })
  827                            })
  828                        })?
  829                        .transpose()?;
  830                        Ok(())
  831                    }
  832                }
  833            })
  834            .detach();
  835
  836        language_server
  837            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  838                let this = this.clone();
  839                move |(), cx| {
  840                    let this = this.clone();
  841                    let mut cx = cx.clone();
  842                    async move {
  843                        this.update(&mut cx, |lsp_store, _| {
  844                            lsp_store.pull_workspace_diagnostics(server_id);
  845                            lsp_store
  846                                .downstream_client
  847                                .as_ref()
  848                                .map(|(client, project_id)| {
  849                                    client.send(proto::PullWorkspaceDiagnostics {
  850                                        project_id: *project_id,
  851                                        server_id: server_id.to_proto(),
  852                                    })
  853                                })
  854                        })?
  855                        .transpose()?;
  856                        Ok(())
  857                    }
  858                }
  859            })
  860            .detach();
  861
  862        language_server
  863            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  864                let this = this.clone();
  865                let name = name.to_string();
  866                move |params, cx| {
  867                    let this = this.clone();
  868                    let name = name.to_string();
  869                    let mut cx = cx.clone();
  870                    async move {
  871                        let actions = params.actions.unwrap_or_default();
  872                        let (tx, rx) = smol::channel::bounded(1);
  873                        let request = LanguageServerPromptRequest {
  874                            level: match params.typ {
  875                                lsp::MessageType::ERROR => PromptLevel::Critical,
  876                                lsp::MessageType::WARNING => PromptLevel::Warning,
  877                                _ => PromptLevel::Info,
  878                            },
  879                            message: params.message,
  880                            actions,
  881                            response_channel: tx,
  882                            lsp_name: name.clone(),
  883                        };
  884
  885                        let did_update = this
  886                            .update(&mut cx, |_, cx| {
  887                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  888                            })
  889                            .is_ok();
  890                        if did_update {
  891                            let response = rx.recv().await.ok();
  892                            Ok(response)
  893                        } else {
  894                            Ok(None)
  895                        }
  896                    }
  897                }
  898            })
  899            .detach();
  900        language_server
  901            .on_notification::<lsp::notification::ShowMessage, _>({
  902                let this = this.clone();
  903                let name = name.to_string();
  904                move |params, cx| {
  905                    let this = this.clone();
  906                    let name = name.to_string();
  907                    let mut cx = cx.clone();
  908
  909                    let (tx, _) = smol::channel::bounded(1);
  910                    let request = LanguageServerPromptRequest {
  911                        level: match params.typ {
  912                            lsp::MessageType::ERROR => PromptLevel::Critical,
  913                            lsp::MessageType::WARNING => PromptLevel::Warning,
  914                            _ => PromptLevel::Info,
  915                        },
  916                        message: params.message,
  917                        actions: vec![],
  918                        response_channel: tx,
  919                        lsp_name: name,
  920                    };
  921
  922                    let _ = this.update(&mut cx, |_, cx| {
  923                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  924                    });
  925                }
  926            })
  927            .detach();
  928
  929        let disk_based_diagnostics_progress_token =
  930            adapter.disk_based_diagnostics_progress_token.clone();
  931
  932        language_server
  933            .on_notification::<lsp::notification::Progress, _>({
  934                let this = this.clone();
  935                move |params, cx| {
  936                    if let Some(this) = this.upgrade() {
  937                        this.update(cx, |this, cx| {
  938                            this.on_lsp_progress(
  939                                params,
  940                                server_id,
  941                                disk_based_diagnostics_progress_token.clone(),
  942                                cx,
  943                            );
  944                        })
  945                        .ok();
  946                    }
  947                }
  948            })
  949            .detach();
  950
  951        language_server
  952            .on_notification::<lsp::notification::LogMessage, _>({
  953                let this = this.clone();
  954                move |params, cx| {
  955                    if let Some(this) = this.upgrade() {
  956                        this.update(cx, |_, cx| {
  957                            cx.emit(LspStoreEvent::LanguageServerLog(
  958                                server_id,
  959                                LanguageServerLogType::Log(params.typ),
  960                                params.message,
  961                            ));
  962                        })
  963                        .ok();
  964                    }
  965                }
  966            })
  967            .detach();
  968
  969        language_server
  970            .on_notification::<lsp::notification::LogTrace, _>({
  971                let this = this.clone();
  972                move |params, cx| {
  973                    let mut cx = cx.clone();
  974                    if let Some(this) = this.upgrade() {
  975                        this.update(&mut cx, |_, cx| {
  976                            cx.emit(LspStoreEvent::LanguageServerLog(
  977                                server_id,
  978                                LanguageServerLogType::Trace {
  979                                    verbose_info: params.verbose,
  980                                },
  981                                params.message,
  982                            ));
  983                        })
  984                        .ok();
  985                    }
  986                }
  987            })
  988            .detach();
  989
  990        json_language_server_ext::register_requests(this.clone(), language_server);
  991        rust_analyzer_ext::register_notifications(this.clone(), language_server);
  992        clangd_ext::register_notifications(this, language_server, adapter);
  993    }
  994
  995    fn shutdown_language_servers_on_quit(
  996        &mut self,
  997        _: &mut Context<LspStore>,
  998    ) -> impl Future<Output = ()> + use<> {
  999        let shutdown_futures = self
 1000            .language_servers
 1001            .drain()
 1002            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1003            .collect::<Vec<_>>();
 1004
 1005        async move {
 1006            join_all(shutdown_futures).await;
 1007        }
 1008    }
 1009
 1010    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1011        match server_state {
 1012            LanguageServerState::Running { server, .. } => {
 1013                if let Some(shutdown) = server.shutdown() {
 1014                    shutdown.await;
 1015                }
 1016            }
 1017            LanguageServerState::Starting { startup, .. } => {
 1018                if let Some(server) = startup.await
 1019                    && let Some(shutdown) = server.shutdown()
 1020                {
 1021                    shutdown.await;
 1022                }
 1023            }
 1024        }
 1025        Ok(())
 1026    }
 1027
 1028    fn language_servers_for_worktree(
 1029        &self,
 1030        worktree_id: WorktreeId,
 1031    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1032        self.language_server_ids
 1033            .iter()
 1034            .filter_map(move |(seed, state)| {
 1035                if seed.worktree_id != worktree_id {
 1036                    return None;
 1037                }
 1038
 1039                if let Some(LanguageServerState::Running { server, .. }) =
 1040                    self.language_servers.get(&state.id)
 1041                {
 1042                    Some(server)
 1043                } else {
 1044                    None
 1045                }
 1046            })
 1047    }
 1048
 1049    fn language_server_ids_for_project_path(
 1050        &self,
 1051        project_path: ProjectPath,
 1052        language: &Language,
 1053        cx: &mut App,
 1054    ) -> Vec<LanguageServerId> {
 1055        let Some(worktree) = self
 1056            .worktree_store
 1057            .read(cx)
 1058            .worktree_for_id(project_path.worktree_id, cx)
 1059        else {
 1060            return Vec::new();
 1061        };
 1062        let delegate: Arc<dyn ManifestDelegate> =
 1063            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1064
 1065        self.lsp_tree
 1066            .get(
 1067                project_path,
 1068                language.name(),
 1069                language.manifest(),
 1070                &delegate,
 1071                cx,
 1072            )
 1073            .collect::<Vec<_>>()
 1074    }
 1075
 1076    fn language_server_ids_for_buffer(
 1077        &self,
 1078        buffer: &Buffer,
 1079        cx: &mut App,
 1080    ) -> Vec<LanguageServerId> {
 1081        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1082            let worktree_id = file.worktree_id(cx);
 1083
 1084            let path: Arc<Path> = file
 1085                .path()
 1086                .parent()
 1087                .map(Arc::from)
 1088                .unwrap_or_else(|| file.path().clone());
 1089            let worktree_path = ProjectPath { worktree_id, path };
 1090            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1091        } else {
 1092            Vec::new()
 1093        }
 1094    }
 1095
 1096    fn language_servers_for_buffer<'a>(
 1097        &'a self,
 1098        buffer: &'a Buffer,
 1099        cx: &'a mut App,
 1100    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1101        self.language_server_ids_for_buffer(buffer, cx)
 1102            .into_iter()
 1103            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1104                LanguageServerState::Running {
 1105                    adapter, server, ..
 1106                } => Some((adapter, server)),
 1107                _ => None,
 1108            })
 1109    }
 1110
 1111    async fn execute_code_action_kind_locally(
 1112        lsp_store: WeakEntity<LspStore>,
 1113        mut buffers: Vec<Entity<Buffer>>,
 1114        kind: CodeActionKind,
 1115        push_to_history: bool,
 1116        cx: &mut AsyncApp,
 1117    ) -> anyhow::Result<ProjectTransaction> {
 1118        // Do not allow multiple concurrent code actions requests for the
 1119        // same buffer.
 1120        lsp_store.update(cx, |this, cx| {
 1121            let this = this.as_local_mut().unwrap();
 1122            buffers.retain(|buffer| {
 1123                this.buffers_being_formatted
 1124                    .insert(buffer.read(cx).remote_id())
 1125            });
 1126        })?;
 1127        let _cleanup = defer({
 1128            let this = lsp_store.clone();
 1129            let mut cx = cx.clone();
 1130            let buffers = &buffers;
 1131            move || {
 1132                this.update(&mut cx, |this, cx| {
 1133                    let this = this.as_local_mut().unwrap();
 1134                    for buffer in buffers {
 1135                        this.buffers_being_formatted
 1136                            .remove(&buffer.read(cx).remote_id());
 1137                    }
 1138                })
 1139                .ok();
 1140            }
 1141        });
 1142        let mut project_transaction = ProjectTransaction::default();
 1143
 1144        for buffer in &buffers {
 1145            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1146                buffer.update(cx, |buffer, cx| {
 1147                    lsp_store
 1148                        .as_local()
 1149                        .unwrap()
 1150                        .language_servers_for_buffer(buffer, cx)
 1151                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1152                        .collect::<Vec<_>>()
 1153                })
 1154            })?;
 1155            for (_, language_server) in adapters_and_servers.iter() {
 1156                let actions = Self::get_server_code_actions_from_action_kinds(
 1157                    &lsp_store,
 1158                    language_server.server_id(),
 1159                    vec![kind.clone()],
 1160                    buffer,
 1161                    cx,
 1162                )
 1163                .await?;
 1164                Self::execute_code_actions_on_server(
 1165                    &lsp_store,
 1166                    language_server,
 1167                    actions,
 1168                    push_to_history,
 1169                    &mut project_transaction,
 1170                    cx,
 1171                )
 1172                .await?;
 1173            }
 1174        }
 1175        Ok(project_transaction)
 1176    }
 1177
 1178    async fn format_locally(
 1179        lsp_store: WeakEntity<LspStore>,
 1180        mut buffers: Vec<FormattableBuffer>,
 1181        push_to_history: bool,
 1182        trigger: FormatTrigger,
 1183        logger: zlog::Logger,
 1184        cx: &mut AsyncApp,
 1185    ) -> anyhow::Result<ProjectTransaction> {
 1186        // Do not allow multiple concurrent formatting requests for the
 1187        // same buffer.
 1188        lsp_store.update(cx, |this, cx| {
 1189            let this = this.as_local_mut().unwrap();
 1190            buffers.retain(|buffer| {
 1191                this.buffers_being_formatted
 1192                    .insert(buffer.handle.read(cx).remote_id())
 1193            });
 1194        })?;
 1195
 1196        let _cleanup = defer({
 1197            let this = lsp_store.clone();
 1198            let mut cx = cx.clone();
 1199            let buffers = &buffers;
 1200            move || {
 1201                this.update(&mut cx, |this, cx| {
 1202                    let this = this.as_local_mut().unwrap();
 1203                    for buffer in buffers {
 1204                        this.buffers_being_formatted
 1205                            .remove(&buffer.handle.read(cx).remote_id());
 1206                    }
 1207                })
 1208                .ok();
 1209            }
 1210        });
 1211
 1212        let mut project_transaction = ProjectTransaction::default();
 1213
 1214        for buffer in &buffers {
 1215            zlog::debug!(
 1216                logger =>
 1217                "formatting buffer '{:?}'",
 1218                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1219            );
 1220            // Create an empty transaction to hold all of the formatting edits.
 1221            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1222                // ensure no transactions created while formatting are
 1223                // grouped with the previous transaction in the history
 1224                // based on the transaction group interval
 1225                buffer.finalize_last_transaction();
 1226                buffer
 1227                    .start_transaction()
 1228                    .context("transaction already open")?;
 1229                buffer.end_transaction(cx);
 1230                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1231                buffer.finalize_last_transaction();
 1232                anyhow::Ok(transaction_id)
 1233            })??;
 1234
 1235            let result = Self::format_buffer_locally(
 1236                lsp_store.clone(),
 1237                buffer,
 1238                formatting_transaction_id,
 1239                trigger,
 1240                logger,
 1241                cx,
 1242            )
 1243            .await;
 1244
 1245            buffer.handle.update(cx, |buffer, cx| {
 1246                let Some(formatting_transaction) =
 1247                    buffer.get_transaction(formatting_transaction_id).cloned()
 1248                else {
 1249                    zlog::warn!(logger => "no formatting transaction");
 1250                    return;
 1251                };
 1252                if formatting_transaction.edit_ids.is_empty() {
 1253                    zlog::debug!(logger => "no changes made while formatting");
 1254                    buffer.forget_transaction(formatting_transaction_id);
 1255                    return;
 1256                }
 1257                if !push_to_history {
 1258                    zlog::trace!(logger => "forgetting format transaction");
 1259                    buffer.forget_transaction(formatting_transaction.id);
 1260                }
 1261                project_transaction
 1262                    .0
 1263                    .insert(cx.entity(), formatting_transaction);
 1264            })?;
 1265
 1266            result?;
 1267        }
 1268
 1269        Ok(project_transaction)
 1270    }
 1271
 1272    async fn format_buffer_locally(
 1273        lsp_store: WeakEntity<LspStore>,
 1274        buffer: &FormattableBuffer,
 1275        formatting_transaction_id: clock::Lamport,
 1276        trigger: FormatTrigger,
 1277        logger: zlog::Logger,
 1278        cx: &mut AsyncApp,
 1279    ) -> Result<()> {
 1280        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1281            buffer.handle.update(cx, |buffer, cx| {
 1282                let adapters_and_servers = lsp_store
 1283                    .as_local()
 1284                    .unwrap()
 1285                    .language_servers_for_buffer(buffer, cx)
 1286                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1287                    .collect::<Vec<_>>();
 1288                let settings =
 1289                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1290                        .into_owned();
 1291                (adapters_and_servers, settings)
 1292            })
 1293        })?;
 1294
 1295        /// Apply edits to the buffer that will become part of the formatting transaction.
 1296        /// Fails if the buffer has been edited since the start of that transaction.
 1297        fn extend_formatting_transaction(
 1298            buffer: &FormattableBuffer,
 1299            formatting_transaction_id: text::TransactionId,
 1300            cx: &mut AsyncApp,
 1301            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1302        ) -> anyhow::Result<()> {
 1303            buffer.handle.update(cx, |buffer, cx| {
 1304                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1305                if last_transaction_id != Some(formatting_transaction_id) {
 1306                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1307                }
 1308                buffer.start_transaction();
 1309                operation(buffer, cx);
 1310                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1311                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1312                }
 1313                Ok(())
 1314            })?
 1315        }
 1316
 1317        // handle whitespace formatting
 1318        if settings.remove_trailing_whitespace_on_save {
 1319            zlog::trace!(logger => "removing trailing whitespace");
 1320            let diff = buffer
 1321                .handle
 1322                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1323                .await;
 1324            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1325                buffer.apply_diff(diff, cx);
 1326            })?;
 1327        }
 1328
 1329        if settings.ensure_final_newline_on_save {
 1330            zlog::trace!(logger => "ensuring final newline");
 1331            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1332                buffer.ensure_final_newline(cx);
 1333            })?;
 1334        }
 1335
 1336        // Formatter for `code_actions_on_format` that runs before
 1337        // the rest of the formatters
 1338        let mut code_actions_on_format_formatter = None;
 1339        let should_run_code_actions_on_format = !matches!(
 1340            (trigger, &settings.format_on_save),
 1341            (FormatTrigger::Save, &FormatOnSave::Off)
 1342        );
 1343        if should_run_code_actions_on_format {
 1344            let have_code_actions_to_run_on_format = settings
 1345                .code_actions_on_format
 1346                .values()
 1347                .any(|enabled| *enabled);
 1348            if have_code_actions_to_run_on_format {
 1349                zlog::trace!(logger => "going to run code actions on format");
 1350                code_actions_on_format_formatter = Some(Formatter::CodeActions(
 1351                    settings.code_actions_on_format.clone(),
 1352                ));
 1353            }
 1354        }
 1355
 1356        let formatters = match (trigger, &settings.format_on_save) {
 1357            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1358            (FormatTrigger::Save, FormatOnSave::List(formatters)) => formatters.as_ref(),
 1359            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1360                match &settings.formatter {
 1361                    SelectedFormatter::Auto => {
 1362                        if settings.prettier.allowed {
 1363                            zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1364                            std::slice::from_ref(&Formatter::Prettier)
 1365                        } else {
 1366                            zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1367                            std::slice::from_ref(&Formatter::LanguageServer { name: None })
 1368                        }
 1369                    }
 1370                    SelectedFormatter::List(formatter_list) => formatter_list.as_ref(),
 1371                }
 1372            }
 1373        };
 1374
 1375        let formatters = code_actions_on_format_formatter.iter().chain(formatters);
 1376
 1377        for formatter in formatters {
 1378            match formatter {
 1379                Formatter::Prettier => {
 1380                    let logger = zlog::scoped!(logger => "prettier");
 1381                    zlog::trace!(logger => "formatting");
 1382                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1383
 1384                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1385                        lsp_store.prettier_store().unwrap().downgrade()
 1386                    })?;
 1387                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1388                        .await
 1389                        .transpose()?;
 1390                    let Some(diff) = diff else {
 1391                        zlog::trace!(logger => "No changes");
 1392                        continue;
 1393                    };
 1394
 1395                    extend_formatting_transaction(
 1396                        buffer,
 1397                        formatting_transaction_id,
 1398                        cx,
 1399                        |buffer, cx| {
 1400                            buffer.apply_diff(diff, cx);
 1401                        },
 1402                    )?;
 1403                }
 1404                Formatter::External { command, arguments } => {
 1405                    let logger = zlog::scoped!(logger => "command");
 1406                    zlog::trace!(logger => "formatting");
 1407                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1408
 1409                    let diff = Self::format_via_external_command(
 1410                        buffer,
 1411                        command.as_ref(),
 1412                        arguments.as_deref(),
 1413                        cx,
 1414                    )
 1415                    .await
 1416                    .with_context(|| {
 1417                        format!("Failed to format buffer via external command: {}", command)
 1418                    })?;
 1419                    let Some(diff) = diff else {
 1420                        zlog::trace!(logger => "No changes");
 1421                        continue;
 1422                    };
 1423
 1424                    extend_formatting_transaction(
 1425                        buffer,
 1426                        formatting_transaction_id,
 1427                        cx,
 1428                        |buffer, cx| {
 1429                            buffer.apply_diff(diff, cx);
 1430                        },
 1431                    )?;
 1432                }
 1433                Formatter::LanguageServer { name } => {
 1434                    let logger = zlog::scoped!(logger => "language-server");
 1435                    zlog::trace!(logger => "formatting");
 1436                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1437
 1438                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1439                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1440                        continue;
 1441                    };
 1442
 1443                    let language_server = if let Some(name) = name.as_deref() {
 1444                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1445                            if adapter.name.0.as_ref() == name {
 1446                                Some(server.clone())
 1447                            } else {
 1448                                None
 1449                            }
 1450                        })
 1451                    } else {
 1452                        adapters_and_servers.first().map(|e| e.1.clone())
 1453                    };
 1454
 1455                    let Some(language_server) = language_server else {
 1456                        log::debug!(
 1457                            "No language server found to format buffer '{:?}'. Skipping",
 1458                            buffer_path_abs.as_path().to_string_lossy()
 1459                        );
 1460                        continue;
 1461                    };
 1462
 1463                    zlog::trace!(
 1464                        logger =>
 1465                        "Formatting buffer '{:?}' using language server '{:?}'",
 1466                        buffer_path_abs.as_path().to_string_lossy(),
 1467                        language_server.name()
 1468                    );
 1469
 1470                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1471                        zlog::trace!(logger => "formatting ranges");
 1472                        Self::format_ranges_via_lsp(
 1473                            &lsp_store,
 1474                            &buffer.handle,
 1475                            ranges,
 1476                            buffer_path_abs,
 1477                            &language_server,
 1478                            &settings,
 1479                            cx,
 1480                        )
 1481                        .await
 1482                        .context("Failed to format ranges via language server")?
 1483                    } else {
 1484                        zlog::trace!(logger => "formatting full");
 1485                        Self::format_via_lsp(
 1486                            &lsp_store,
 1487                            &buffer.handle,
 1488                            buffer_path_abs,
 1489                            &language_server,
 1490                            &settings,
 1491                            cx,
 1492                        )
 1493                        .await
 1494                        .context("failed to format via language server")?
 1495                    };
 1496
 1497                    if edits.is_empty() {
 1498                        zlog::trace!(logger => "No changes");
 1499                        continue;
 1500                    }
 1501                    extend_formatting_transaction(
 1502                        buffer,
 1503                        formatting_transaction_id,
 1504                        cx,
 1505                        |buffer, cx| {
 1506                            buffer.edit(edits, None, cx);
 1507                        },
 1508                    )?;
 1509                }
 1510                Formatter::CodeActions(code_actions) => {
 1511                    let logger = zlog::scoped!(logger => "code-actions");
 1512                    zlog::trace!(logger => "formatting");
 1513                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1514
 1515                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1516                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1517                        continue;
 1518                    };
 1519                    let code_action_kinds = code_actions
 1520                        .iter()
 1521                        .filter_map(|(action_kind, enabled)| {
 1522                            enabled.then_some(action_kind.clone().into())
 1523                        })
 1524                        .collect::<Vec<_>>();
 1525                    if code_action_kinds.is_empty() {
 1526                        zlog::trace!(logger => "No code action kinds enabled, skipping");
 1527                        continue;
 1528                    }
 1529                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kinds);
 1530
 1531                    let mut actions_and_servers = Vec::new();
 1532
 1533                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1534                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1535                            &lsp_store,
 1536                            language_server.server_id(),
 1537                            code_action_kinds.clone(),
 1538                            &buffer.handle,
 1539                            cx,
 1540                        )
 1541                        .await
 1542                        .with_context(
 1543                            || format!("Failed to resolve code actions with kinds {:?} for language server {}",
 1544                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1545                                language_server.name())
 1546                        );
 1547                        let Ok(actions) = actions_result else {
 1548                            // note: it may be better to set result to the error and break formatters here
 1549                            // but for now we try to execute the actions that we can resolve and skip the rest
 1550                            zlog::error!(
 1551                                logger =>
 1552                                "Failed to resolve code actions with kinds {:?} with language server {}",
 1553                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1554                                language_server.name()
 1555                            );
 1556                            continue;
 1557                        };
 1558                        for action in actions {
 1559                            actions_and_servers.push((action, index));
 1560                        }
 1561                    }
 1562
 1563                    if actions_and_servers.is_empty() {
 1564                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1565                        continue;
 1566                    }
 1567
 1568                    'actions: for (mut action, server_index) in actions_and_servers {
 1569                        let server = &adapters_and_servers[server_index].1;
 1570
 1571                        let describe_code_action = |action: &CodeAction| {
 1572                            format!(
 1573                                "code action '{}' with title \"{}\" on server {}",
 1574                                action
 1575                                    .lsp_action
 1576                                    .action_kind()
 1577                                    .unwrap_or("unknown".into())
 1578                                    .as_str(),
 1579                                action.lsp_action.title(),
 1580                                server.name(),
 1581                            )
 1582                        };
 1583
 1584                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1585
 1586                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1587                            zlog::error!(
 1588                                logger =>
 1589                                "Failed to resolve {}. Error: {}",
 1590                                describe_code_action(&action),
 1591                                err
 1592                            );
 1593                            continue;
 1594                        }
 1595
 1596                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1597                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1598                            // but filters out and logs warnings for code actions that cause unreasonably
 1599                            // difficult handling on our part, such as:
 1600                            // - applying edits that call commands
 1601                            //   which can result in arbitrary workspace edits being sent from the server that
 1602                            //   have no way of being tied back to the command that initiated them (i.e. we
 1603                            //   can't know which edits are part of the format request, or if the server is done sending
 1604                            //   actions in response to the command)
 1605                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1606                            //   as we then would need to handle such changes correctly in the local history as well
 1607                            //   as the remote history through the ProjectTransaction
 1608                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1609                            // Supporting these actions is not impossible, but not supported as of yet.
 1610                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1611                                zlog::trace!(
 1612                                    logger =>
 1613                                    "No changes for code action. Skipping {}",
 1614                                    describe_code_action(&action),
 1615                                );
 1616                                continue;
 1617                            }
 1618
 1619                            let mut operations = Vec::new();
 1620                            if let Some(document_changes) = edit.document_changes {
 1621                                match document_changes {
 1622                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1623                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1624                                    ),
 1625                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1626                                }
 1627                            } else if let Some(changes) = edit.changes {
 1628                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1629                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1630                                        text_document:
 1631                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1632                                                uri,
 1633                                                version: None,
 1634                                            },
 1635                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1636                                    })
 1637                                }));
 1638                            }
 1639
 1640                            let mut edits = Vec::with_capacity(operations.len());
 1641
 1642                            if operations.is_empty() {
 1643                                zlog::trace!(
 1644                                    logger =>
 1645                                    "No changes for code action. Skipping {}",
 1646                                    describe_code_action(&action),
 1647                                );
 1648                                continue;
 1649                            }
 1650                            for operation in operations {
 1651                                let op = match operation {
 1652                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1653                                    lsp::DocumentChangeOperation::Op(_) => {
 1654                                        zlog::warn!(
 1655                                            logger =>
 1656                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1657                                            describe_code_action(&action),
 1658                                        );
 1659                                        continue 'actions;
 1660                                    }
 1661                                };
 1662                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1663                                    zlog::warn!(
 1664                                        logger =>
 1665                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1666                                        &op.text_document.uri,
 1667                                        describe_code_action(&action),
 1668                                    );
 1669                                    continue 'actions;
 1670                                };
 1671                                if &file_path != buffer_path_abs {
 1672                                    zlog::warn!(
 1673                                        logger =>
 1674                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1675                                        file_path,
 1676                                        buffer_path_abs,
 1677                                        describe_code_action(&action),
 1678                                    );
 1679                                    continue 'actions;
 1680                                }
 1681
 1682                                let mut lsp_edits = Vec::new();
 1683                                for edit in op.edits {
 1684                                    match edit {
 1685                                        Edit::Plain(edit) => {
 1686                                            if !lsp_edits.contains(&edit) {
 1687                                                lsp_edits.push(edit);
 1688                                            }
 1689                                        }
 1690                                        Edit::Annotated(edit) => {
 1691                                            if !lsp_edits.contains(&edit.text_edit) {
 1692                                                lsp_edits.push(edit.text_edit);
 1693                                            }
 1694                                        }
 1695                                        Edit::Snippet(_) => {
 1696                                            zlog::warn!(
 1697                                                logger =>
 1698                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1699                                                describe_code_action(&action),
 1700                                            );
 1701                                            continue 'actions;
 1702                                        }
 1703                                    }
 1704                                }
 1705                                let edits_result = lsp_store
 1706                                    .update(cx, |lsp_store, cx| {
 1707                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1708                                            &buffer.handle,
 1709                                            lsp_edits,
 1710                                            server.server_id(),
 1711                                            op.text_document.version,
 1712                                            cx,
 1713                                        )
 1714                                    })?
 1715                                    .await;
 1716                                let Ok(resolved_edits) = edits_result else {
 1717                                    zlog::warn!(
 1718                                        logger =>
 1719                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1720                                        buffer_path_abs.as_path(),
 1721                                        describe_code_action(&action),
 1722                                    );
 1723                                    continue 'actions;
 1724                                };
 1725                                edits.extend(resolved_edits);
 1726                            }
 1727
 1728                            if edits.is_empty() {
 1729                                zlog::warn!(logger => "No edits resolved from LSP");
 1730                                continue;
 1731                            }
 1732
 1733                            extend_formatting_transaction(
 1734                                buffer,
 1735                                formatting_transaction_id,
 1736                                cx,
 1737                                |buffer, cx| {
 1738                                    buffer.edit(edits, None, cx);
 1739                                },
 1740                            )?;
 1741                        }
 1742
 1743                        if let Some(command) = action.lsp_action.command() {
 1744                            zlog::warn!(
 1745                                logger =>
 1746                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1747                                &command.command,
 1748                            );
 1749
 1750                            // bail early if command is invalid
 1751                            let server_capabilities = server.capabilities();
 1752                            let available_commands = server_capabilities
 1753                                .execute_command_provider
 1754                                .as_ref()
 1755                                .map(|options| options.commands.as_slice())
 1756                                .unwrap_or_default();
 1757                            if !available_commands.contains(&command.command) {
 1758                                zlog::warn!(
 1759                                    logger =>
 1760                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1761                                    command.command,
 1762                                    server.name(),
 1763                                );
 1764                                continue;
 1765                            }
 1766
 1767                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1768                            extend_formatting_transaction(
 1769                                buffer,
 1770                                formatting_transaction_id,
 1771                                cx,
 1772                                |_, _| {},
 1773                            )?;
 1774                            zlog::info!(logger => "Executing command {}", &command.command);
 1775
 1776                            lsp_store.update(cx, |this, _| {
 1777                                this.as_local_mut()
 1778                                    .unwrap()
 1779                                    .last_workspace_edits_by_language_server
 1780                                    .remove(&server.server_id());
 1781                            })?;
 1782
 1783                            let execute_command_result = server
 1784                                .request::<lsp::request::ExecuteCommand>(
 1785                                    lsp::ExecuteCommandParams {
 1786                                        command: command.command.clone(),
 1787                                        arguments: command.arguments.clone().unwrap_or_default(),
 1788                                        ..Default::default()
 1789                                    },
 1790                                )
 1791                                .await
 1792                                .into_response();
 1793
 1794                            if execute_command_result.is_err() {
 1795                                zlog::error!(
 1796                                    logger =>
 1797                                    "Failed to execute command '{}' as part of {}",
 1798                                    &command.command,
 1799                                    describe_code_action(&action),
 1800                                );
 1801                                continue 'actions;
 1802                            }
 1803
 1804                            let mut project_transaction_command =
 1805                                lsp_store.update(cx, |this, _| {
 1806                                    this.as_local_mut()
 1807                                        .unwrap()
 1808                                        .last_workspace_edits_by_language_server
 1809                                        .remove(&server.server_id())
 1810                                        .unwrap_or_default()
 1811                                })?;
 1812
 1813                            if let Some(transaction) =
 1814                                project_transaction_command.0.remove(&buffer.handle)
 1815                            {
 1816                                zlog::trace!(
 1817                                    logger =>
 1818                                    "Successfully captured {} edits that resulted from command {}",
 1819                                    transaction.edit_ids.len(),
 1820                                    &command.command,
 1821                                );
 1822                                let transaction_id_project_transaction = transaction.id;
 1823                                buffer.handle.update(cx, |buffer, _| {
 1824                                    // it may have been removed from history if push_to_history was
 1825                                    // false in deserialize_workspace_edit. If so push it so we
 1826                                    // can merge it with the format transaction
 1827                                    // and pop the combined transaction off the history stack
 1828                                    // later if push_to_history is false
 1829                                    if buffer.get_transaction(transaction.id).is_none() {
 1830                                        buffer.push_transaction(transaction, Instant::now());
 1831                                    }
 1832                                    buffer.merge_transactions(
 1833                                        transaction_id_project_transaction,
 1834                                        formatting_transaction_id,
 1835                                    );
 1836                                })?;
 1837                            }
 1838
 1839                            if !project_transaction_command.0.is_empty() {
 1840                                let extra_buffers = project_transaction_command
 1841                                    .0
 1842                                    .keys()
 1843                                    .filter_map(|buffer_handle| {
 1844                                        buffer_handle
 1845                                            .read_with(cx, |b, cx| b.project_path(cx))
 1846                                            .ok()
 1847                                            .flatten()
 1848                                    })
 1849                                    .map(|p| p.path.to_sanitized_string())
 1850                                    .join(", ");
 1851                                zlog::warn!(
 1852                                    logger =>
 1853                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1854                                    &command.command,
 1855                                    extra_buffers,
 1856                                );
 1857                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1858                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1859                                // add it so it's included, and merge it into the format transaction when its created later
 1860                            }
 1861                        }
 1862                    }
 1863                }
 1864            }
 1865        }
 1866
 1867        Ok(())
 1868    }
 1869
 1870    pub async fn format_ranges_via_lsp(
 1871        this: &WeakEntity<LspStore>,
 1872        buffer_handle: &Entity<Buffer>,
 1873        ranges: &[Range<Anchor>],
 1874        abs_path: &Path,
 1875        language_server: &Arc<LanguageServer>,
 1876        settings: &LanguageSettings,
 1877        cx: &mut AsyncApp,
 1878    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1879        let capabilities = &language_server.capabilities();
 1880        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1881        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1882            anyhow::bail!(
 1883                "{} language server does not support range formatting",
 1884                language_server.name()
 1885            );
 1886        }
 1887
 1888        let uri = file_path_to_lsp_url(abs_path)?;
 1889        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1890
 1891        let lsp_edits = {
 1892            let mut lsp_ranges = Vec::new();
 1893            this.update(cx, |_this, cx| {
 1894                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1895                // not have been sent to the language server. This seems like a fairly systemic
 1896                // issue, though, the resolution probably is not specific to formatting.
 1897                //
 1898                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1899                // LSP.
 1900                let snapshot = buffer_handle.read(cx).snapshot();
 1901                for range in ranges {
 1902                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1903                }
 1904                anyhow::Ok(())
 1905            })??;
 1906
 1907            let mut edits = None;
 1908            for range in lsp_ranges {
 1909                if let Some(mut edit) = language_server
 1910                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1911                        text_document: text_document.clone(),
 1912                        range,
 1913                        options: lsp_command::lsp_formatting_options(settings),
 1914                        work_done_progress_params: Default::default(),
 1915                    })
 1916                    .await
 1917                    .into_response()?
 1918                {
 1919                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1920                }
 1921            }
 1922            edits
 1923        };
 1924
 1925        if let Some(lsp_edits) = lsp_edits {
 1926            this.update(cx, |this, cx| {
 1927                this.as_local_mut().unwrap().edits_from_lsp(
 1928                    buffer_handle,
 1929                    lsp_edits,
 1930                    language_server.server_id(),
 1931                    None,
 1932                    cx,
 1933                )
 1934            })?
 1935            .await
 1936        } else {
 1937            Ok(Vec::with_capacity(0))
 1938        }
 1939    }
 1940
 1941    async fn format_via_lsp(
 1942        this: &WeakEntity<LspStore>,
 1943        buffer: &Entity<Buffer>,
 1944        abs_path: &Path,
 1945        language_server: &Arc<LanguageServer>,
 1946        settings: &LanguageSettings,
 1947        cx: &mut AsyncApp,
 1948    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1949        let logger = zlog::scoped!("lsp_format");
 1950        zlog::info!(logger => "Formatting via LSP");
 1951
 1952        let uri = file_path_to_lsp_url(abs_path)?;
 1953        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1954        let capabilities = &language_server.capabilities();
 1955
 1956        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1957        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1958
 1959        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1960            let _timer = zlog::time!(logger => "format-full");
 1961            language_server
 1962                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1963                    text_document,
 1964                    options: lsp_command::lsp_formatting_options(settings),
 1965                    work_done_progress_params: Default::default(),
 1966                })
 1967                .await
 1968                .into_response()?
 1969        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1970            let _timer = zlog::time!(logger => "format-range");
 1971            let buffer_start = lsp::Position::new(0, 0);
 1972            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1973            language_server
 1974                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1975                    text_document: text_document.clone(),
 1976                    range: lsp::Range::new(buffer_start, buffer_end),
 1977                    options: lsp_command::lsp_formatting_options(settings),
 1978                    work_done_progress_params: Default::default(),
 1979                })
 1980                .await
 1981                .into_response()?
 1982        } else {
 1983            None
 1984        };
 1985
 1986        if let Some(lsp_edits) = lsp_edits {
 1987            this.update(cx, |this, cx| {
 1988                this.as_local_mut().unwrap().edits_from_lsp(
 1989                    buffer,
 1990                    lsp_edits,
 1991                    language_server.server_id(),
 1992                    None,
 1993                    cx,
 1994                )
 1995            })?
 1996            .await
 1997        } else {
 1998            Ok(Vec::with_capacity(0))
 1999        }
 2000    }
 2001
 2002    async fn format_via_external_command(
 2003        buffer: &FormattableBuffer,
 2004        command: &str,
 2005        arguments: Option<&[String]>,
 2006        cx: &mut AsyncApp,
 2007    ) -> Result<Option<Diff>> {
 2008        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2009            let file = File::from_dyn(buffer.file())?;
 2010            let worktree = file.worktree.read(cx);
 2011            let mut worktree_path = worktree.abs_path().to_path_buf();
 2012            if worktree.root_entry()?.is_file() {
 2013                worktree_path.pop();
 2014            }
 2015            Some(worktree_path)
 2016        })?;
 2017
 2018        let mut child = util::command::new_smol_command(command);
 2019
 2020        if let Some(buffer_env) = buffer.env.as_ref() {
 2021            child.envs(buffer_env);
 2022        }
 2023
 2024        if let Some(working_dir_path) = working_dir_path {
 2025            child.current_dir(working_dir_path);
 2026        }
 2027
 2028        if let Some(arguments) = arguments {
 2029            child.args(arguments.iter().map(|arg| {
 2030                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2031                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2032                } else {
 2033                    arg.replace("{buffer_path}", "Untitled")
 2034                }
 2035            }));
 2036        }
 2037
 2038        let mut child = child
 2039            .stdin(smol::process::Stdio::piped())
 2040            .stdout(smol::process::Stdio::piped())
 2041            .stderr(smol::process::Stdio::piped())
 2042            .spawn()?;
 2043
 2044        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2045        let text = buffer
 2046            .handle
 2047            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2048        for chunk in text.chunks() {
 2049            stdin.write_all(chunk.as_bytes()).await?;
 2050        }
 2051        stdin.flush().await?;
 2052
 2053        let output = child.output().await?;
 2054        anyhow::ensure!(
 2055            output.status.success(),
 2056            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2057            output.status.code(),
 2058            String::from_utf8_lossy(&output.stdout),
 2059            String::from_utf8_lossy(&output.stderr),
 2060        );
 2061
 2062        let stdout = String::from_utf8(output.stdout)?;
 2063        Ok(Some(
 2064            buffer
 2065                .handle
 2066                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2067                .await,
 2068        ))
 2069    }
 2070
 2071    async fn try_resolve_code_action(
 2072        lang_server: &LanguageServer,
 2073        action: &mut CodeAction,
 2074    ) -> anyhow::Result<()> {
 2075        match &mut action.lsp_action {
 2076            LspAction::Action(lsp_action) => {
 2077                if !action.resolved
 2078                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2079                    && lsp_action.data.is_some()
 2080                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2081                {
 2082                    *lsp_action = Box::new(
 2083                        lang_server
 2084                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2085                            .await
 2086                            .into_response()?,
 2087                    );
 2088                }
 2089            }
 2090            LspAction::CodeLens(lens) => {
 2091                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2092                    *lens = lang_server
 2093                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2094                        .await
 2095                        .into_response()?;
 2096                }
 2097            }
 2098            LspAction::Command(_) => {}
 2099        }
 2100
 2101        action.resolved = true;
 2102        anyhow::Ok(())
 2103    }
 2104
 2105    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2106        let buffer = buffer_handle.read(cx);
 2107
 2108        let file = buffer.file().cloned();
 2109
 2110        let Some(file) = File::from_dyn(file.as_ref()) else {
 2111            return;
 2112        };
 2113        if !file.is_local() {
 2114            return;
 2115        }
 2116        let path = ProjectPath::from_file(file, cx);
 2117        let worktree_id = file.worktree_id(cx);
 2118        let language = buffer.language().cloned();
 2119
 2120        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2121            for (server_id, diagnostics) in
 2122                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2123            {
 2124                self.update_buffer_diagnostics(
 2125                    buffer_handle,
 2126                    server_id,
 2127                    None,
 2128                    None,
 2129                    diagnostics,
 2130                    Vec::new(),
 2131                    cx,
 2132                )
 2133                .log_err();
 2134            }
 2135        }
 2136        let Some(language) = language else {
 2137            return;
 2138        };
 2139        let Some(snapshot) = self
 2140            .worktree_store
 2141            .read(cx)
 2142            .worktree_for_id(worktree_id, cx)
 2143            .map(|worktree| worktree.read(cx).snapshot())
 2144        else {
 2145            return;
 2146        };
 2147        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2148
 2149        for server_id in
 2150            self.lsp_tree
 2151                .get(path, language.name(), language.manifest(), &delegate, cx)
 2152        {
 2153            let server = self
 2154                .language_servers
 2155                .get(&server_id)
 2156                .and_then(|server_state| {
 2157                    if let LanguageServerState::Running { server, .. } = server_state {
 2158                        Some(server.clone())
 2159                    } else {
 2160                        None
 2161                    }
 2162                });
 2163            let server = match server {
 2164                Some(server) => server,
 2165                None => continue,
 2166            };
 2167
 2168            buffer_handle.update(cx, |buffer, cx| {
 2169                buffer.set_completion_triggers(
 2170                    server.server_id(),
 2171                    server
 2172                        .capabilities()
 2173                        .completion_provider
 2174                        .as_ref()
 2175                        .and_then(|provider| {
 2176                            provider
 2177                                .trigger_characters
 2178                                .as_ref()
 2179                                .map(|characters| characters.iter().cloned().collect())
 2180                        })
 2181                        .unwrap_or_default(),
 2182                    cx,
 2183                );
 2184            });
 2185        }
 2186    }
 2187
 2188    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2189        buffer.update(cx, |buffer, cx| {
 2190            let Some(language) = buffer.language() else {
 2191                return;
 2192            };
 2193            let path = ProjectPath {
 2194                worktree_id: old_file.worktree_id(cx),
 2195                path: old_file.path.clone(),
 2196            };
 2197            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2198                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2199                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2200            }
 2201        });
 2202    }
 2203
 2204    fn update_buffer_diagnostics(
 2205        &mut self,
 2206        buffer: &Entity<Buffer>,
 2207        server_id: LanguageServerId,
 2208        result_id: Option<String>,
 2209        version: Option<i32>,
 2210        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2211        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2212        cx: &mut Context<LspStore>,
 2213    ) -> Result<()> {
 2214        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2215            Ordering::Equal
 2216                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2217                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2218                .then_with(|| a.severity.cmp(&b.severity))
 2219                .then_with(|| a.message.cmp(&b.message))
 2220        }
 2221
 2222        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2223        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2224        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2225
 2226        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2227            Ordering::Equal
 2228                .then_with(|| a.range.start.cmp(&b.range.start))
 2229                .then_with(|| b.range.end.cmp(&a.range.end))
 2230                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2231        });
 2232
 2233        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2234
 2235        let edits_since_save = std::cell::LazyCell::new(|| {
 2236            let saved_version = buffer.read(cx).saved_version();
 2237            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2238        });
 2239
 2240        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2241
 2242        for (new_diagnostic, entry) in diagnostics {
 2243            let start;
 2244            let end;
 2245            if new_diagnostic && entry.diagnostic.is_disk_based {
 2246                // Some diagnostics are based on files on disk instead of buffers'
 2247                // current contents. Adjust these diagnostics' ranges to reflect
 2248                // any unsaved edits.
 2249                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2250                // and were properly adjusted on reuse.
 2251                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2252                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2253            } else {
 2254                start = entry.range.start;
 2255                end = entry.range.end;
 2256            }
 2257
 2258            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2259                ..snapshot.clip_point_utf16(end, Bias::Right);
 2260
 2261            // Expand empty ranges by one codepoint
 2262            if range.start == range.end {
 2263                // This will be go to the next boundary when being clipped
 2264                range.end.column += 1;
 2265                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2266                if range.start == range.end && range.end.column > 0 {
 2267                    range.start.column -= 1;
 2268                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2269                }
 2270            }
 2271
 2272            sanitized_diagnostics.push(DiagnosticEntry {
 2273                range,
 2274                diagnostic: entry.diagnostic,
 2275            });
 2276        }
 2277        drop(edits_since_save);
 2278
 2279        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2280        buffer.update(cx, |buffer, cx| {
 2281            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2282                self.buffer_pull_diagnostics_result_ids
 2283                    .entry(server_id)
 2284                    .or_default()
 2285                    .insert(abs_path, result_id);
 2286            }
 2287
 2288            buffer.update_diagnostics(server_id, set, cx)
 2289        });
 2290
 2291        Ok(())
 2292    }
 2293
 2294    fn register_language_server_for_invisible_worktree(
 2295        &mut self,
 2296        worktree: &Entity<Worktree>,
 2297        language_server_id: LanguageServerId,
 2298        cx: &mut App,
 2299    ) {
 2300        let worktree = worktree.read(cx);
 2301        let worktree_id = worktree.id();
 2302        debug_assert!(!worktree.is_visible());
 2303        let Some(mut origin_seed) = self
 2304            .language_server_ids
 2305            .iter()
 2306            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2307        else {
 2308            return;
 2309        };
 2310        origin_seed.worktree_id = worktree_id;
 2311        self.language_server_ids
 2312            .entry(origin_seed)
 2313            .or_insert_with(|| UnifiedLanguageServer {
 2314                id: language_server_id,
 2315                project_roots: Default::default(),
 2316            });
 2317    }
 2318
 2319    fn register_buffer_with_language_servers(
 2320        &mut self,
 2321        buffer_handle: &Entity<Buffer>,
 2322        only_register_servers: HashSet<LanguageServerSelector>,
 2323        cx: &mut Context<LspStore>,
 2324    ) {
 2325        let buffer = buffer_handle.read(cx);
 2326        let buffer_id = buffer.remote_id();
 2327
 2328        let Some(file) = File::from_dyn(buffer.file()) else {
 2329            return;
 2330        };
 2331        if !file.is_local() {
 2332            return;
 2333        }
 2334
 2335        let abs_path = file.abs_path(cx);
 2336        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2337            return;
 2338        };
 2339        let initial_snapshot = buffer.text_snapshot();
 2340        let worktree_id = file.worktree_id(cx);
 2341
 2342        let Some(language) = buffer.language().cloned() else {
 2343            return;
 2344        };
 2345        let path: Arc<Path> = file
 2346            .path()
 2347            .parent()
 2348            .map(Arc::from)
 2349            .unwrap_or_else(|| file.path().clone());
 2350        let Some(worktree) = self
 2351            .worktree_store
 2352            .read(cx)
 2353            .worktree_for_id(worktree_id, cx)
 2354        else {
 2355            return;
 2356        };
 2357        let language_name = language.name();
 2358        let (reused, delegate, servers) = self
 2359            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2360            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2361            .unwrap_or_else(|| {
 2362                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2363                let delegate: Arc<dyn ManifestDelegate> =
 2364                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2365
 2366                let servers = self
 2367                    .lsp_tree
 2368                    .walk(
 2369                        ProjectPath { worktree_id, path },
 2370                        language.name(),
 2371                        language.manifest(),
 2372                        &delegate,
 2373                        cx,
 2374                    )
 2375                    .collect::<Vec<_>>();
 2376                (false, lsp_delegate, servers)
 2377            });
 2378        let servers_and_adapters = servers
 2379            .into_iter()
 2380            .filter_map(|server_node| {
 2381                if reused && server_node.server_id().is_none() {
 2382                    return None;
 2383                }
 2384                if !only_register_servers.is_empty() {
 2385                    if let Some(server_id) = server_node.server_id()
 2386                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2387                    {
 2388                        return None;
 2389                    }
 2390                    if let Some(name) = server_node.name()
 2391                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2392                    {
 2393                        return None;
 2394                    }
 2395                }
 2396
 2397                let server_id = server_node.server_id_or_init(|disposition| {
 2398                    let path = &disposition.path;
 2399
 2400                    {
 2401                        let uri =
 2402                            Uri::from_file_path(worktree.read(cx).abs_path().join(&path.path));
 2403
 2404                        let server_id = self.get_or_insert_language_server(
 2405                            &worktree,
 2406                            delegate.clone(),
 2407                            disposition,
 2408                            &language_name,
 2409                            cx,
 2410                        );
 2411
 2412                        if let Some(state) = self.language_servers.get(&server_id)
 2413                            && let Ok(uri) = uri
 2414                        {
 2415                            state.add_workspace_folder(uri);
 2416                        };
 2417                        server_id
 2418                    }
 2419                })?;
 2420                let server_state = self.language_servers.get(&server_id)?;
 2421                if let LanguageServerState::Running {
 2422                    server, adapter, ..
 2423                } = server_state
 2424                {
 2425                    Some((server.clone(), adapter.clone()))
 2426                } else {
 2427                    None
 2428                }
 2429            })
 2430            .collect::<Vec<_>>();
 2431        for (server, adapter) in servers_and_adapters {
 2432            buffer_handle.update(cx, |buffer, cx| {
 2433                buffer.set_completion_triggers(
 2434                    server.server_id(),
 2435                    server
 2436                        .capabilities()
 2437                        .completion_provider
 2438                        .as_ref()
 2439                        .and_then(|provider| {
 2440                            provider
 2441                                .trigger_characters
 2442                                .as_ref()
 2443                                .map(|characters| characters.iter().cloned().collect())
 2444                        })
 2445                        .unwrap_or_default(),
 2446                    cx,
 2447                );
 2448            });
 2449
 2450            let snapshot = LspBufferSnapshot {
 2451                version: 0,
 2452                snapshot: initial_snapshot.clone(),
 2453            };
 2454
 2455            let mut registered = false;
 2456            self.buffer_snapshots
 2457                .entry(buffer_id)
 2458                .or_default()
 2459                .entry(server.server_id())
 2460                .or_insert_with(|| {
 2461                    registered = true;
 2462                    server.register_buffer(
 2463                        uri.clone(),
 2464                        adapter.language_id(&language.name()),
 2465                        0,
 2466                        initial_snapshot.text(),
 2467                    );
 2468
 2469                    vec![snapshot]
 2470                });
 2471
 2472            self.buffers_opened_in_servers
 2473                .entry(buffer_id)
 2474                .or_default()
 2475                .insert(server.server_id());
 2476            if registered {
 2477                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2478                    language_server_id: server.server_id(),
 2479                    name: None,
 2480                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2481                        proto::RegisteredForBuffer {
 2482                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2483                            buffer_id: buffer_id.to_proto(),
 2484                        },
 2485                    ),
 2486                });
 2487            }
 2488        }
 2489    }
 2490
 2491    fn reuse_existing_language_server<'lang_name>(
 2492        &self,
 2493        server_tree: &LanguageServerTree,
 2494        worktree: &Entity<Worktree>,
 2495        language_name: &'lang_name LanguageName,
 2496        cx: &mut App,
 2497    ) -> Option<(
 2498        Arc<LocalLspAdapterDelegate>,
 2499        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2500    )> {
 2501        if worktree.read(cx).is_visible() {
 2502            return None;
 2503        }
 2504
 2505        let worktree_store = self.worktree_store.read(cx);
 2506        let servers = server_tree
 2507            .instances
 2508            .iter()
 2509            .filter(|(worktree_id, _)| {
 2510                worktree_store
 2511                    .worktree_for_id(**worktree_id, cx)
 2512                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2513            })
 2514            .flat_map(|(worktree_id, servers)| {
 2515                servers
 2516                    .roots
 2517                    .iter()
 2518                    .flat_map(|(_, language_servers)| language_servers)
 2519                    .map(move |(_, (server_node, server_languages))| {
 2520                        (worktree_id, server_node, server_languages)
 2521                    })
 2522                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2523                    .map(|(worktree_id, server_node, _)| {
 2524                        (
 2525                            *worktree_id,
 2526                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2527                        )
 2528                    })
 2529            })
 2530            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2531                acc.entry(worktree_id)
 2532                    .or_insert_with(Vec::new)
 2533                    .push(server_node);
 2534                acc
 2535            })
 2536            .into_values()
 2537            .max_by_key(|servers| servers.len())?;
 2538
 2539        let worktree_id = worktree.read(cx).id();
 2540        let apply = move |tree: &mut LanguageServerTree| {
 2541            for server_node in &servers {
 2542                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2543            }
 2544            servers
 2545        };
 2546
 2547        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2548        Some((delegate, apply))
 2549    }
 2550
 2551    pub(crate) fn unregister_old_buffer_from_language_servers(
 2552        &mut self,
 2553        buffer: &Entity<Buffer>,
 2554        old_file: &File,
 2555        cx: &mut App,
 2556    ) {
 2557        let old_path = match old_file.as_local() {
 2558            Some(local) => local.abs_path(cx),
 2559            None => return,
 2560        };
 2561
 2562        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2563            debug_panic!("{old_path:?} is not parseable as an URI");
 2564            return;
 2565        };
 2566        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2567    }
 2568
 2569    pub(crate) fn unregister_buffer_from_language_servers(
 2570        &mut self,
 2571        buffer: &Entity<Buffer>,
 2572        file_url: &lsp::Uri,
 2573        cx: &mut App,
 2574    ) {
 2575        buffer.update(cx, |buffer, cx| {
 2576            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2577
 2578            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2579                language_server.unregister_buffer(file_url.clone());
 2580            }
 2581        });
 2582    }
 2583
 2584    fn buffer_snapshot_for_lsp_version(
 2585        &mut self,
 2586        buffer: &Entity<Buffer>,
 2587        server_id: LanguageServerId,
 2588        version: Option<i32>,
 2589        cx: &App,
 2590    ) -> Result<TextBufferSnapshot> {
 2591        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2592
 2593        if let Some(version) = version {
 2594            let buffer_id = buffer.read(cx).remote_id();
 2595            let snapshots = if let Some(snapshots) = self
 2596                .buffer_snapshots
 2597                .get_mut(&buffer_id)
 2598                .and_then(|m| m.get_mut(&server_id))
 2599            {
 2600                snapshots
 2601            } else if version == 0 {
 2602                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2603                // We detect this case and treat it as if the version was `None`.
 2604                return Ok(buffer.read(cx).text_snapshot());
 2605            } else {
 2606                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2607            };
 2608
 2609            let found_snapshot = snapshots
 2610                    .binary_search_by_key(&version, |e| e.version)
 2611                    .map(|ix| snapshots[ix].snapshot.clone())
 2612                    .map_err(|_| {
 2613                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2614                    })?;
 2615
 2616            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2617            Ok(found_snapshot)
 2618        } else {
 2619            Ok((buffer.read(cx)).text_snapshot())
 2620        }
 2621    }
 2622
 2623    async fn get_server_code_actions_from_action_kinds(
 2624        lsp_store: &WeakEntity<LspStore>,
 2625        language_server_id: LanguageServerId,
 2626        code_action_kinds: Vec<lsp::CodeActionKind>,
 2627        buffer: &Entity<Buffer>,
 2628        cx: &mut AsyncApp,
 2629    ) -> Result<Vec<CodeAction>> {
 2630        let actions = lsp_store
 2631            .update(cx, move |this, cx| {
 2632                let request = GetCodeActions {
 2633                    range: text::Anchor::MIN..text::Anchor::MAX,
 2634                    kinds: Some(code_action_kinds),
 2635                };
 2636                let server = LanguageServerToQuery::Other(language_server_id);
 2637                this.request_lsp(buffer.clone(), server, request, cx)
 2638            })?
 2639            .await?;
 2640        Ok(actions)
 2641    }
 2642
 2643    pub async fn execute_code_actions_on_server(
 2644        lsp_store: &WeakEntity<LspStore>,
 2645        language_server: &Arc<LanguageServer>,
 2646
 2647        actions: Vec<CodeAction>,
 2648        push_to_history: bool,
 2649        project_transaction: &mut ProjectTransaction,
 2650        cx: &mut AsyncApp,
 2651    ) -> anyhow::Result<()> {
 2652        for mut action in actions {
 2653            Self::try_resolve_code_action(language_server, &mut action)
 2654                .await
 2655                .context("resolving a formatting code action")?;
 2656
 2657            if let Some(edit) = action.lsp_action.edit() {
 2658                if edit.changes.is_none() && edit.document_changes.is_none() {
 2659                    continue;
 2660                }
 2661
 2662                let new = Self::deserialize_workspace_edit(
 2663                    lsp_store.upgrade().context("project dropped")?,
 2664                    edit.clone(),
 2665                    push_to_history,
 2666                    language_server.clone(),
 2667                    cx,
 2668                )
 2669                .await?;
 2670                project_transaction.0.extend(new.0);
 2671            }
 2672
 2673            if let Some(command) = action.lsp_action.command() {
 2674                let server_capabilities = language_server.capabilities();
 2675                let available_commands = server_capabilities
 2676                    .execute_command_provider
 2677                    .as_ref()
 2678                    .map(|options| options.commands.as_slice())
 2679                    .unwrap_or_default();
 2680                if available_commands.contains(&command.command) {
 2681                    lsp_store.update(cx, |lsp_store, _| {
 2682                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2683                            mode.last_workspace_edits_by_language_server
 2684                                .remove(&language_server.server_id());
 2685                        }
 2686                    })?;
 2687
 2688                    language_server
 2689                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2690                            command: command.command.clone(),
 2691                            arguments: command.arguments.clone().unwrap_or_default(),
 2692                            ..Default::default()
 2693                        })
 2694                        .await
 2695                        .into_response()
 2696                        .context("execute command")?;
 2697
 2698                    lsp_store.update(cx, |this, _| {
 2699                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2700                            project_transaction.0.extend(
 2701                                mode.last_workspace_edits_by_language_server
 2702                                    .remove(&language_server.server_id())
 2703                                    .unwrap_or_default()
 2704                                    .0,
 2705                            )
 2706                        }
 2707                    })?;
 2708                } else {
 2709                    log::warn!(
 2710                        "Cannot execute a command {} not listed in the language server capabilities",
 2711                        command.command
 2712                    )
 2713                }
 2714            }
 2715        }
 2716        Ok(())
 2717    }
 2718
 2719    pub async fn deserialize_text_edits(
 2720        this: Entity<LspStore>,
 2721        buffer_to_edit: Entity<Buffer>,
 2722        edits: Vec<lsp::TextEdit>,
 2723        push_to_history: bool,
 2724        _: Arc<CachedLspAdapter>,
 2725        language_server: Arc<LanguageServer>,
 2726        cx: &mut AsyncApp,
 2727    ) -> Result<Option<Transaction>> {
 2728        let edits = this
 2729            .update(cx, |this, cx| {
 2730                this.as_local_mut().unwrap().edits_from_lsp(
 2731                    &buffer_to_edit,
 2732                    edits,
 2733                    language_server.server_id(),
 2734                    None,
 2735                    cx,
 2736                )
 2737            })?
 2738            .await?;
 2739
 2740        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2741            buffer.finalize_last_transaction();
 2742            buffer.start_transaction();
 2743            for (range, text) in edits {
 2744                buffer.edit([(range, text)], None, cx);
 2745            }
 2746
 2747            if buffer.end_transaction(cx).is_some() {
 2748                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2749                if !push_to_history {
 2750                    buffer.forget_transaction(transaction.id);
 2751                }
 2752                Some(transaction)
 2753            } else {
 2754                None
 2755            }
 2756        })?;
 2757
 2758        Ok(transaction)
 2759    }
 2760
 2761    #[allow(clippy::type_complexity)]
 2762    pub(crate) fn edits_from_lsp(
 2763        &mut self,
 2764        buffer: &Entity<Buffer>,
 2765        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2766        server_id: LanguageServerId,
 2767        version: Option<i32>,
 2768        cx: &mut Context<LspStore>,
 2769    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2770        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2771        cx.background_spawn(async move {
 2772            let snapshot = snapshot?;
 2773            let mut lsp_edits = lsp_edits
 2774                .into_iter()
 2775                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2776                .collect::<Vec<_>>();
 2777
 2778            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2779
 2780            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2781            let mut edits = Vec::new();
 2782            while let Some((range, mut new_text)) = lsp_edits.next() {
 2783                // Clip invalid ranges provided by the language server.
 2784                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2785                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2786
 2787                // Combine any LSP edits that are adjacent.
 2788                //
 2789                // Also, combine LSP edits that are separated from each other by only
 2790                // a newline. This is important because for some code actions,
 2791                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2792                // are separated by unchanged newline characters.
 2793                //
 2794                // In order for the diffing logic below to work properly, any edits that
 2795                // cancel each other out must be combined into one.
 2796                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2797                    if next_range.start.0 > range.end {
 2798                        if next_range.start.0.row > range.end.row + 1
 2799                            || next_range.start.0.column > 0
 2800                            || snapshot.clip_point_utf16(
 2801                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2802                                Bias::Left,
 2803                            ) > range.end
 2804                        {
 2805                            break;
 2806                        }
 2807                        new_text.push('\n');
 2808                    }
 2809                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2810                    new_text.push_str(next_text);
 2811                    lsp_edits.next();
 2812                }
 2813
 2814                // For multiline edits, perform a diff of the old and new text so that
 2815                // we can identify the changes more precisely, preserving the locations
 2816                // of any anchors positioned in the unchanged regions.
 2817                if range.end.row > range.start.row {
 2818                    let offset = range.start.to_offset(&snapshot);
 2819                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2820                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2821                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2822                        (
 2823                            snapshot.anchor_after(offset + range.start)
 2824                                ..snapshot.anchor_before(offset + range.end),
 2825                            replacement,
 2826                        )
 2827                    }));
 2828                } else if range.end == range.start {
 2829                    let anchor = snapshot.anchor_after(range.start);
 2830                    edits.push((anchor..anchor, new_text.into()));
 2831                } else {
 2832                    let edit_start = snapshot.anchor_after(range.start);
 2833                    let edit_end = snapshot.anchor_before(range.end);
 2834                    edits.push((edit_start..edit_end, new_text.into()));
 2835                }
 2836            }
 2837
 2838            Ok(edits)
 2839        })
 2840    }
 2841
 2842    pub(crate) async fn deserialize_workspace_edit(
 2843        this: Entity<LspStore>,
 2844        edit: lsp::WorkspaceEdit,
 2845        push_to_history: bool,
 2846        language_server: Arc<LanguageServer>,
 2847        cx: &mut AsyncApp,
 2848    ) -> Result<ProjectTransaction> {
 2849        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2850
 2851        let mut operations = Vec::new();
 2852        if let Some(document_changes) = edit.document_changes {
 2853            match document_changes {
 2854                lsp::DocumentChanges::Edits(edits) => {
 2855                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2856                }
 2857                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2858            }
 2859        } else if let Some(changes) = edit.changes {
 2860            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2861                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2862                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2863                        uri,
 2864                        version: None,
 2865                    },
 2866                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2867                })
 2868            }));
 2869        }
 2870
 2871        let mut project_transaction = ProjectTransaction::default();
 2872        for operation in operations {
 2873            match operation {
 2874                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2875                    let abs_path = op
 2876                        .uri
 2877                        .to_file_path()
 2878                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2879
 2880                    if let Some(parent_path) = abs_path.parent() {
 2881                        fs.create_dir(parent_path).await?;
 2882                    }
 2883                    if abs_path.ends_with("/") {
 2884                        fs.create_dir(&abs_path).await?;
 2885                    } else {
 2886                        fs.create_file(
 2887                            &abs_path,
 2888                            op.options
 2889                                .map(|options| fs::CreateOptions {
 2890                                    overwrite: options.overwrite.unwrap_or(false),
 2891                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2892                                })
 2893                                .unwrap_or_default(),
 2894                        )
 2895                        .await?;
 2896                    }
 2897                }
 2898
 2899                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2900                    let source_abs_path = op
 2901                        .old_uri
 2902                        .to_file_path()
 2903                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2904                    let target_abs_path = op
 2905                        .new_uri
 2906                        .to_file_path()
 2907                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2908                    fs.rename(
 2909                        &source_abs_path,
 2910                        &target_abs_path,
 2911                        op.options
 2912                            .map(|options| fs::RenameOptions {
 2913                                overwrite: options.overwrite.unwrap_or(false),
 2914                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2915                            })
 2916                            .unwrap_or_default(),
 2917                    )
 2918                    .await?;
 2919                }
 2920
 2921                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2922                    let abs_path = op
 2923                        .uri
 2924                        .to_file_path()
 2925                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2926                    let options = op
 2927                        .options
 2928                        .map(|options| fs::RemoveOptions {
 2929                            recursive: options.recursive.unwrap_or(false),
 2930                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2931                        })
 2932                        .unwrap_or_default();
 2933                    if abs_path.ends_with("/") {
 2934                        fs.remove_dir(&abs_path, options).await?;
 2935                    } else {
 2936                        fs.remove_file(&abs_path, options).await?;
 2937                    }
 2938                }
 2939
 2940                lsp::DocumentChangeOperation::Edit(op) => {
 2941                    let buffer_to_edit = this
 2942                        .update(cx, |this, cx| {
 2943                            this.open_local_buffer_via_lsp(
 2944                                op.text_document.uri.clone(),
 2945                                language_server.server_id(),
 2946                                cx,
 2947                            )
 2948                        })?
 2949                        .await?;
 2950
 2951                    let edits = this
 2952                        .update(cx, |this, cx| {
 2953                            let path = buffer_to_edit.read(cx).project_path(cx);
 2954                            let active_entry = this.active_entry;
 2955                            let is_active_entry = path.is_some_and(|project_path| {
 2956                                this.worktree_store
 2957                                    .read(cx)
 2958                                    .entry_for_path(&project_path, cx)
 2959                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2960                            });
 2961                            let local = this.as_local_mut().unwrap();
 2962
 2963                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2964                            for edit in op.edits {
 2965                                match edit {
 2966                                    Edit::Plain(edit) => {
 2967                                        if !edits.contains(&edit) {
 2968                                            edits.push(edit)
 2969                                        }
 2970                                    }
 2971                                    Edit::Annotated(edit) => {
 2972                                        if !edits.contains(&edit.text_edit) {
 2973                                            edits.push(edit.text_edit)
 2974                                        }
 2975                                    }
 2976                                    Edit::Snippet(edit) => {
 2977                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2978                                        else {
 2979                                            continue;
 2980                                        };
 2981
 2982                                        if is_active_entry {
 2983                                            snippet_edits.push((edit.range, snippet));
 2984                                        } else {
 2985                                            // Since this buffer is not focused, apply a normal edit.
 2986                                            let new_edit = TextEdit {
 2987                                                range: edit.range,
 2988                                                new_text: snippet.text,
 2989                                            };
 2990                                            if !edits.contains(&new_edit) {
 2991                                                edits.push(new_edit);
 2992                                            }
 2993                                        }
 2994                                    }
 2995                                }
 2996                            }
 2997                            if !snippet_edits.is_empty() {
 2998                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 2999                                let version = if let Some(buffer_version) = op.text_document.version
 3000                                {
 3001                                    local
 3002                                        .buffer_snapshot_for_lsp_version(
 3003                                            &buffer_to_edit,
 3004                                            language_server.server_id(),
 3005                                            Some(buffer_version),
 3006                                            cx,
 3007                                        )
 3008                                        .ok()
 3009                                        .map(|snapshot| snapshot.version)
 3010                                } else {
 3011                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3012                                };
 3013
 3014                                let most_recent_edit = version.and_then(|version| {
 3015                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3016                                });
 3017                                // Check if the edit that triggered that edit has been made by this participant.
 3018
 3019                                if let Some(most_recent_edit) = most_recent_edit {
 3020                                    cx.emit(LspStoreEvent::SnippetEdit {
 3021                                        buffer_id,
 3022                                        edits: snippet_edits,
 3023                                        most_recent_edit,
 3024                                    });
 3025                                }
 3026                            }
 3027
 3028                            local.edits_from_lsp(
 3029                                &buffer_to_edit,
 3030                                edits,
 3031                                language_server.server_id(),
 3032                                op.text_document.version,
 3033                                cx,
 3034                            )
 3035                        })?
 3036                        .await?;
 3037
 3038                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3039                        buffer.finalize_last_transaction();
 3040                        buffer.start_transaction();
 3041                        for (range, text) in edits {
 3042                            buffer.edit([(range, text)], None, cx);
 3043                        }
 3044
 3045                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3046                            if push_to_history {
 3047                                buffer.finalize_last_transaction();
 3048                                buffer.get_transaction(transaction_id).cloned()
 3049                            } else {
 3050                                buffer.forget_transaction(transaction_id)
 3051                            }
 3052                        })
 3053                    })?;
 3054                    if let Some(transaction) = transaction {
 3055                        project_transaction.0.insert(buffer_to_edit, transaction);
 3056                    }
 3057                }
 3058            }
 3059        }
 3060
 3061        Ok(project_transaction)
 3062    }
 3063
 3064    async fn on_lsp_workspace_edit(
 3065        this: WeakEntity<LspStore>,
 3066        params: lsp::ApplyWorkspaceEditParams,
 3067        server_id: LanguageServerId,
 3068        cx: &mut AsyncApp,
 3069    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3070        let this = this.upgrade().context("project project closed")?;
 3071        let language_server = this
 3072            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3073            .context("language server not found")?;
 3074        let transaction = Self::deserialize_workspace_edit(
 3075            this.clone(),
 3076            params.edit,
 3077            true,
 3078            language_server.clone(),
 3079            cx,
 3080        )
 3081        .await
 3082        .log_err();
 3083        this.update(cx, |this, _| {
 3084            if let Some(transaction) = transaction {
 3085                this.as_local_mut()
 3086                    .unwrap()
 3087                    .last_workspace_edits_by_language_server
 3088                    .insert(server_id, transaction);
 3089            }
 3090        })?;
 3091        Ok(lsp::ApplyWorkspaceEditResponse {
 3092            applied: true,
 3093            failed_change: None,
 3094            failure_reason: None,
 3095        })
 3096    }
 3097
 3098    fn remove_worktree(
 3099        &mut self,
 3100        id_to_remove: WorktreeId,
 3101        cx: &mut Context<LspStore>,
 3102    ) -> Vec<LanguageServerId> {
 3103        self.diagnostics.remove(&id_to_remove);
 3104        self.prettier_store.update(cx, |prettier_store, cx| {
 3105            prettier_store.remove_worktree(id_to_remove, cx);
 3106        });
 3107
 3108        let mut servers_to_remove = BTreeSet::default();
 3109        let mut servers_to_preserve = HashSet::default();
 3110        for (seed, state) in &self.language_server_ids {
 3111            if seed.worktree_id == id_to_remove {
 3112                servers_to_remove.insert(state.id);
 3113            } else {
 3114                servers_to_preserve.insert(state.id);
 3115            }
 3116        }
 3117        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3118        self.language_server_ids
 3119            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3120        for server_id_to_remove in &servers_to_remove {
 3121            self.language_server_watched_paths
 3122                .remove(server_id_to_remove);
 3123            self.language_server_paths_watched_for_rename
 3124                .remove(server_id_to_remove);
 3125            self.last_workspace_edits_by_language_server
 3126                .remove(server_id_to_remove);
 3127            self.language_servers.remove(server_id_to_remove);
 3128            self.buffer_pull_diagnostics_result_ids
 3129                .remove(server_id_to_remove);
 3130            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3131                buffer_servers.remove(server_id_to_remove);
 3132            }
 3133            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3134        }
 3135        servers_to_remove.into_iter().collect()
 3136    }
 3137
 3138    fn rebuild_watched_paths_inner<'a>(
 3139        &'a self,
 3140        language_server_id: LanguageServerId,
 3141        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3142        cx: &mut Context<LspStore>,
 3143    ) -> LanguageServerWatchedPathsBuilder {
 3144        let worktrees = self
 3145            .worktree_store
 3146            .read(cx)
 3147            .worktrees()
 3148            .filter_map(|worktree| {
 3149                self.language_servers_for_worktree(worktree.read(cx).id())
 3150                    .find(|server| server.server_id() == language_server_id)
 3151                    .map(|_| worktree)
 3152            })
 3153            .collect::<Vec<_>>();
 3154
 3155        let mut worktree_globs = HashMap::default();
 3156        let mut abs_globs = HashMap::default();
 3157        log::trace!(
 3158            "Processing new watcher paths for language server with id {}",
 3159            language_server_id
 3160        );
 3161
 3162        for watcher in watchers {
 3163            if let Some((worktree, literal_prefix, pattern)) =
 3164                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3165            {
 3166                worktree.update(cx, |worktree, _| {
 3167                    if let Some((tree, glob)) =
 3168                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3169                    {
 3170                        tree.add_path_prefix_to_scan(literal_prefix.into());
 3171                        worktree_globs
 3172                            .entry(tree.id())
 3173                            .or_insert_with(GlobSetBuilder::new)
 3174                            .add(glob);
 3175                    }
 3176                });
 3177            } else {
 3178                let (path, pattern) = match &watcher.glob_pattern {
 3179                    lsp::GlobPattern::String(s) => {
 3180                        let watcher_path = SanitizedPath::new(s);
 3181                        let path = glob_literal_prefix(watcher_path.as_path());
 3182                        let pattern = watcher_path
 3183                            .as_path()
 3184                            .strip_prefix(&path)
 3185                            .map(|p| p.to_string_lossy().to_string())
 3186                            .unwrap_or_else(|e| {
 3187                                debug_panic!(
 3188                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3189                                    s,
 3190                                    path.display(),
 3191                                    e
 3192                                );
 3193                                watcher_path.as_path().to_string_lossy().to_string()
 3194                            });
 3195                        (path, pattern)
 3196                    }
 3197                    lsp::GlobPattern::Relative(rp) => {
 3198                        let Ok(mut base_uri) = match &rp.base_uri {
 3199                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3200                            lsp::OneOf::Right(base_uri) => base_uri,
 3201                        }
 3202                        .to_file_path() else {
 3203                            continue;
 3204                        };
 3205
 3206                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3207                        let pattern = Path::new(&rp.pattern)
 3208                            .strip_prefix(&path)
 3209                            .map(|p| p.to_string_lossy().to_string())
 3210                            .unwrap_or_else(|e| {
 3211                                debug_panic!(
 3212                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3213                                    rp.pattern,
 3214                                    path.display(),
 3215                                    e
 3216                                );
 3217                                rp.pattern.clone()
 3218                            });
 3219                        base_uri.push(path);
 3220                        (base_uri, pattern)
 3221                    }
 3222                };
 3223
 3224                if let Some(glob) = Glob::new(&pattern).log_err() {
 3225                    if !path
 3226                        .components()
 3227                        .any(|c| matches!(c, path::Component::Normal(_)))
 3228                    {
 3229                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3230                        // rather than adding a new watcher for `/`.
 3231                        for worktree in &worktrees {
 3232                            worktree_globs
 3233                                .entry(worktree.read(cx).id())
 3234                                .or_insert_with(GlobSetBuilder::new)
 3235                                .add(glob.clone());
 3236                        }
 3237                    } else {
 3238                        abs_globs
 3239                            .entry(path.into())
 3240                            .or_insert_with(GlobSetBuilder::new)
 3241                            .add(glob);
 3242                    }
 3243                }
 3244            }
 3245        }
 3246
 3247        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3248        for (worktree_id, builder) in worktree_globs {
 3249            if let Ok(globset) = builder.build() {
 3250                watch_builder.watch_worktree(worktree_id, globset);
 3251            }
 3252        }
 3253        for (abs_path, builder) in abs_globs {
 3254            if let Ok(globset) = builder.build() {
 3255                watch_builder.watch_abs_path(abs_path, globset);
 3256            }
 3257        }
 3258        watch_builder
 3259    }
 3260
 3261    fn worktree_and_path_for_file_watcher(
 3262        &self,
 3263        worktrees: &[Entity<Worktree>],
 3264        watcher: &FileSystemWatcher,
 3265        cx: &App,
 3266    ) -> Option<(Entity<Worktree>, PathBuf, String)> {
 3267        worktrees.iter().find_map(|worktree| {
 3268            let tree = worktree.read(cx);
 3269            let worktree_root_path = tree.abs_path();
 3270            match &watcher.glob_pattern {
 3271                lsp::GlobPattern::String(s) => {
 3272                    let watcher_path = SanitizedPath::new(s);
 3273                    let relative = watcher_path
 3274                        .as_path()
 3275                        .strip_prefix(&worktree_root_path)
 3276                        .ok()?;
 3277                    let literal_prefix = glob_literal_prefix(relative);
 3278                    Some((
 3279                        worktree.clone(),
 3280                        literal_prefix,
 3281                        relative.to_string_lossy().to_string(),
 3282                    ))
 3283                }
 3284                lsp::GlobPattern::Relative(rp) => {
 3285                    let base_uri = match &rp.base_uri {
 3286                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3287                        lsp::OneOf::Right(base_uri) => base_uri,
 3288                    }
 3289                    .to_file_path()
 3290                    .ok()?;
 3291                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3292                    let mut literal_prefix = relative.to_owned();
 3293                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3294                    Some((worktree.clone(), literal_prefix, rp.pattern.clone()))
 3295                }
 3296            }
 3297        })
 3298    }
 3299
 3300    fn rebuild_watched_paths(
 3301        &mut self,
 3302        language_server_id: LanguageServerId,
 3303        cx: &mut Context<LspStore>,
 3304    ) {
 3305        let Some(watchers) = self
 3306            .language_server_watcher_registrations
 3307            .get(&language_server_id)
 3308        else {
 3309            return;
 3310        };
 3311
 3312        let watch_builder =
 3313            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3314        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3315        self.language_server_watched_paths
 3316            .insert(language_server_id, watcher);
 3317
 3318        cx.notify();
 3319    }
 3320
 3321    fn on_lsp_did_change_watched_files(
 3322        &mut self,
 3323        language_server_id: LanguageServerId,
 3324        registration_id: &str,
 3325        params: DidChangeWatchedFilesRegistrationOptions,
 3326        cx: &mut Context<LspStore>,
 3327    ) {
 3328        let registrations = self
 3329            .language_server_watcher_registrations
 3330            .entry(language_server_id)
 3331            .or_default();
 3332
 3333        registrations.insert(registration_id.to_string(), params.watchers);
 3334
 3335        self.rebuild_watched_paths(language_server_id, cx);
 3336    }
 3337
 3338    fn on_lsp_unregister_did_change_watched_files(
 3339        &mut self,
 3340        language_server_id: LanguageServerId,
 3341        registration_id: &str,
 3342        cx: &mut Context<LspStore>,
 3343    ) {
 3344        let registrations = self
 3345            .language_server_watcher_registrations
 3346            .entry(language_server_id)
 3347            .or_default();
 3348
 3349        if registrations.remove(registration_id).is_some() {
 3350            log::info!(
 3351                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3352                language_server_id,
 3353                registration_id
 3354            );
 3355        } else {
 3356            log::warn!(
 3357                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3358                language_server_id,
 3359                registration_id
 3360            );
 3361        }
 3362
 3363        self.rebuild_watched_paths(language_server_id, cx);
 3364    }
 3365
 3366    async fn initialization_options_for_adapter(
 3367        adapter: Arc<dyn LspAdapter>,
 3368        delegate: &Arc<dyn LspAdapterDelegate>,
 3369    ) -> Result<Option<serde_json::Value>> {
 3370        let Some(mut initialization_config) =
 3371            adapter.clone().initialization_options(delegate).await?
 3372        else {
 3373            return Ok(None);
 3374        };
 3375
 3376        for other_adapter in delegate.registered_lsp_adapters() {
 3377            if other_adapter.name() == adapter.name() {
 3378                continue;
 3379            }
 3380            if let Ok(Some(target_config)) = other_adapter
 3381                .clone()
 3382                .additional_initialization_options(adapter.name(), delegate)
 3383                .await
 3384            {
 3385                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3386            }
 3387        }
 3388
 3389        Ok(Some(initialization_config))
 3390    }
 3391
 3392    async fn workspace_configuration_for_adapter(
 3393        adapter: Arc<dyn LspAdapter>,
 3394        delegate: &Arc<dyn LspAdapterDelegate>,
 3395        toolchain: Option<Toolchain>,
 3396        cx: &mut AsyncApp,
 3397    ) -> Result<serde_json::Value> {
 3398        let mut workspace_config = adapter
 3399            .clone()
 3400            .workspace_configuration(delegate, toolchain, cx)
 3401            .await?;
 3402
 3403        for other_adapter in delegate.registered_lsp_adapters() {
 3404            if other_adapter.name() == adapter.name() {
 3405                continue;
 3406            }
 3407            if let Ok(Some(target_config)) = other_adapter
 3408                .clone()
 3409                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3410                .await
 3411            {
 3412                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3413            }
 3414        }
 3415
 3416        Ok(workspace_config)
 3417    }
 3418
 3419    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3420        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3421            Some(server.clone())
 3422        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3423            Some(Arc::clone(server))
 3424        } else {
 3425            None
 3426        }
 3427    }
 3428}
 3429
 3430fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3431    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3432        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3433            language_server_id: server.server_id(),
 3434            name: Some(server.name()),
 3435            message: proto::update_language_server::Variant::MetadataUpdated(
 3436                proto::ServerMetadataUpdated {
 3437                    capabilities: Some(capabilities),
 3438                },
 3439            ),
 3440        });
 3441    }
 3442}
 3443
 3444#[derive(Debug)]
 3445pub struct FormattableBuffer {
 3446    handle: Entity<Buffer>,
 3447    abs_path: Option<PathBuf>,
 3448    env: Option<HashMap<String, String>>,
 3449    ranges: Option<Vec<Range<Anchor>>>,
 3450}
 3451
 3452pub struct RemoteLspStore {
 3453    upstream_client: Option<AnyProtoClient>,
 3454    upstream_project_id: u64,
 3455}
 3456
 3457pub(crate) enum LspStoreMode {
 3458    Local(LocalLspStore),   // ssh host and collab host
 3459    Remote(RemoteLspStore), // collab guest
 3460}
 3461
 3462impl LspStoreMode {
 3463    fn is_local(&self) -> bool {
 3464        matches!(self, LspStoreMode::Local(_))
 3465    }
 3466}
 3467
 3468pub struct LspStore {
 3469    mode: LspStoreMode,
 3470    last_formatting_failure: Option<String>,
 3471    downstream_client: Option<(AnyProtoClient, u64)>,
 3472    nonce: u128,
 3473    buffer_store: Entity<BufferStore>,
 3474    worktree_store: Entity<WorktreeStore>,
 3475    pub languages: Arc<LanguageRegistry>,
 3476    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3477    active_entry: Option<ProjectEntryId>,
 3478    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3479    _maintain_buffer_languages: Task<()>,
 3480    diagnostic_summaries:
 3481        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3482    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3483    lsp_document_colors: HashMap<BufferId, DocumentColorData>,
 3484    lsp_code_lens: HashMap<BufferId, CodeLensData>,
 3485    running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
 3486}
 3487
 3488#[derive(Debug, Default, Clone)]
 3489pub struct DocumentColors {
 3490    pub colors: HashSet<DocumentColor>,
 3491    pub cache_version: Option<usize>,
 3492}
 3493
 3494type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3495type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3496
 3497#[derive(Debug, Default)]
 3498struct DocumentColorData {
 3499    colors_for_version: Global,
 3500    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3501    cache_version: usize,
 3502    colors_update: Option<(Global, DocumentColorTask)>,
 3503}
 3504
 3505#[derive(Debug, Default)]
 3506struct CodeLensData {
 3507    lens_for_version: Global,
 3508    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3509    update: Option<(Global, CodeLensTask)>,
 3510}
 3511
 3512#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 3513pub enum LspFetchStrategy {
 3514    IgnoreCache,
 3515    UseCache { known_cache_version: Option<usize> },
 3516}
 3517
 3518#[derive(Debug)]
 3519pub enum LspStoreEvent {
 3520    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3521    LanguageServerRemoved(LanguageServerId),
 3522    LanguageServerUpdate {
 3523        language_server_id: LanguageServerId,
 3524        name: Option<LanguageServerName>,
 3525        message: proto::update_language_server::Variant,
 3526    },
 3527    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3528    LanguageServerPrompt(LanguageServerPromptRequest),
 3529    LanguageDetected {
 3530        buffer: Entity<Buffer>,
 3531        new_language: Option<Arc<Language>>,
 3532    },
 3533    Notification(String),
 3534    RefreshInlayHints,
 3535    RefreshCodeLens,
 3536    DiagnosticsUpdated {
 3537        server_id: LanguageServerId,
 3538        paths: Vec<ProjectPath>,
 3539    },
 3540    DiskBasedDiagnosticsStarted {
 3541        language_server_id: LanguageServerId,
 3542    },
 3543    DiskBasedDiagnosticsFinished {
 3544        language_server_id: LanguageServerId,
 3545    },
 3546    SnippetEdit {
 3547        buffer_id: BufferId,
 3548        edits: Vec<(lsp::Range, Snippet)>,
 3549        most_recent_edit: clock::Lamport,
 3550    },
 3551}
 3552
 3553#[derive(Clone, Debug, Serialize)]
 3554pub struct LanguageServerStatus {
 3555    pub name: LanguageServerName,
 3556    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3557    pub has_pending_diagnostic_updates: bool,
 3558    progress_tokens: HashSet<String>,
 3559    pub worktree: Option<WorktreeId>,
 3560}
 3561
 3562#[derive(Clone, Debug)]
 3563struct CoreSymbol {
 3564    pub language_server_name: LanguageServerName,
 3565    pub source_worktree_id: WorktreeId,
 3566    pub source_language_server_id: LanguageServerId,
 3567    pub path: ProjectPath,
 3568    pub name: String,
 3569    pub kind: lsp::SymbolKind,
 3570    pub range: Range<Unclipped<PointUtf16>>,
 3571    pub signature: [u8; 32],
 3572}
 3573
 3574impl LspStore {
 3575    pub fn init(client: &AnyProtoClient) {
 3576        client.add_entity_request_handler(Self::handle_lsp_query);
 3577        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3578        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3579        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3580        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3581        client.add_entity_message_handler(Self::handle_start_language_server);
 3582        client.add_entity_message_handler(Self::handle_update_language_server);
 3583        client.add_entity_message_handler(Self::handle_language_server_log);
 3584        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3585        client.add_entity_request_handler(Self::handle_format_buffers);
 3586        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3587        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3588        client.add_entity_request_handler(Self::handle_apply_code_action);
 3589        client.add_entity_request_handler(Self::handle_inlay_hints);
 3590        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3591        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3592        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3593        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3594        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3595        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3596        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3597        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3598        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3599        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3600        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3601        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3602        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3603        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3604        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3605        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3606        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3607
 3608        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3609        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3610        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3611        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3612        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3613        client.add_entity_request_handler(
 3614            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3615        );
 3616        client.add_entity_request_handler(
 3617            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3618        );
 3619        client.add_entity_request_handler(
 3620            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3621        );
 3622    }
 3623
 3624    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3625        match &self.mode {
 3626            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3627            _ => None,
 3628        }
 3629    }
 3630
 3631    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3632        match &self.mode {
 3633            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3634            _ => None,
 3635        }
 3636    }
 3637
 3638    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3639        match &mut self.mode {
 3640            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3641            _ => None,
 3642        }
 3643    }
 3644
 3645    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3646        match &self.mode {
 3647            LspStoreMode::Remote(RemoteLspStore {
 3648                upstream_client: Some(upstream_client),
 3649                upstream_project_id,
 3650                ..
 3651            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3652
 3653            LspStoreMode::Remote(RemoteLspStore {
 3654                upstream_client: None,
 3655                ..
 3656            }) => None,
 3657            LspStoreMode::Local(_) => None,
 3658        }
 3659    }
 3660
 3661    pub fn new_local(
 3662        buffer_store: Entity<BufferStore>,
 3663        worktree_store: Entity<WorktreeStore>,
 3664        prettier_store: Entity<PrettierStore>,
 3665        toolchain_store: Entity<LocalToolchainStore>,
 3666        environment: Entity<ProjectEnvironment>,
 3667        manifest_tree: Entity<ManifestTree>,
 3668        languages: Arc<LanguageRegistry>,
 3669        http_client: Arc<dyn HttpClient>,
 3670        fs: Arc<dyn Fs>,
 3671        cx: &mut Context<Self>,
 3672    ) -> Self {
 3673        let yarn = YarnPathStore::new(fs.clone(), cx);
 3674        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3675            .detach();
 3676        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3677            .detach();
 3678        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3679            .detach();
 3680        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3681            .detach();
 3682        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3683            cx.subscribe(
 3684                extension_events,
 3685                Self::reload_zed_json_schemas_on_extensions_changed,
 3686            )
 3687            .detach();
 3688        } else {
 3689            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3690        }
 3691        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3692            .detach();
 3693        subscribe_to_binary_statuses(&languages, cx).detach();
 3694
 3695        let _maintain_workspace_config = {
 3696            let (sender, receiver) = watch::channel();
 3697            (Self::maintain_workspace_config(receiver, cx), sender)
 3698        };
 3699
 3700        Self {
 3701            mode: LspStoreMode::Local(LocalLspStore {
 3702                weak: cx.weak_entity(),
 3703                worktree_store: worktree_store.clone(),
 3704
 3705                supplementary_language_servers: Default::default(),
 3706                languages: languages.clone(),
 3707                language_server_ids: Default::default(),
 3708                language_servers: Default::default(),
 3709                last_workspace_edits_by_language_server: Default::default(),
 3710                language_server_watched_paths: Default::default(),
 3711                language_server_paths_watched_for_rename: Default::default(),
 3712                language_server_watcher_registrations: Default::default(),
 3713                buffers_being_formatted: Default::default(),
 3714                buffer_snapshots: Default::default(),
 3715                prettier_store,
 3716                environment,
 3717                http_client,
 3718                fs,
 3719                yarn,
 3720                next_diagnostic_group_id: Default::default(),
 3721                diagnostics: Default::default(),
 3722                _subscription: cx.on_app_quit(|this, cx| {
 3723                    this.as_local_mut()
 3724                        .unwrap()
 3725                        .shutdown_language_servers_on_quit(cx)
 3726                }),
 3727                lsp_tree: LanguageServerTree::new(
 3728                    manifest_tree,
 3729                    languages.clone(),
 3730                    toolchain_store.clone(),
 3731                ),
 3732                toolchain_store,
 3733                registered_buffers: HashMap::default(),
 3734                buffers_opened_in_servers: HashMap::default(),
 3735                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3736                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3737                    .manifest_file_names(),
 3738            }),
 3739            last_formatting_failure: None,
 3740            downstream_client: None,
 3741            buffer_store,
 3742            worktree_store,
 3743            languages: languages.clone(),
 3744            language_server_statuses: Default::default(),
 3745            nonce: StdRng::from_os_rng().random(),
 3746            diagnostic_summaries: HashMap::default(),
 3747            lsp_server_capabilities: HashMap::default(),
 3748            lsp_document_colors: HashMap::default(),
 3749            lsp_code_lens: HashMap::default(),
 3750            running_lsp_requests: HashMap::default(),
 3751            active_entry: None,
 3752            _maintain_workspace_config,
 3753            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3754        }
 3755    }
 3756
 3757    fn send_lsp_proto_request<R: LspCommand>(
 3758        &self,
 3759        buffer: Entity<Buffer>,
 3760        client: AnyProtoClient,
 3761        upstream_project_id: u64,
 3762        request: R,
 3763        cx: &mut Context<LspStore>,
 3764    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3765        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3766            return Task::ready(Ok(R::Response::default()));
 3767        }
 3768        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3769        cx.spawn(async move |this, cx| {
 3770            let response = client.request(message).await?;
 3771            let this = this.upgrade().context("project dropped")?;
 3772            request
 3773                .response_from_proto(response, this, buffer, cx.clone())
 3774                .await
 3775        })
 3776    }
 3777
 3778    pub(super) fn new_remote(
 3779        buffer_store: Entity<BufferStore>,
 3780        worktree_store: Entity<WorktreeStore>,
 3781        languages: Arc<LanguageRegistry>,
 3782        upstream_client: AnyProtoClient,
 3783        project_id: u64,
 3784        cx: &mut Context<Self>,
 3785    ) -> Self {
 3786        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3787            .detach();
 3788        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3789            .detach();
 3790        subscribe_to_binary_statuses(&languages, cx).detach();
 3791        let _maintain_workspace_config = {
 3792            let (sender, receiver) = watch::channel();
 3793            (Self::maintain_workspace_config(receiver, cx), sender)
 3794        };
 3795        Self {
 3796            mode: LspStoreMode::Remote(RemoteLspStore {
 3797                upstream_client: Some(upstream_client),
 3798                upstream_project_id: project_id,
 3799            }),
 3800            downstream_client: None,
 3801            last_formatting_failure: None,
 3802            buffer_store,
 3803            worktree_store,
 3804            languages: languages.clone(),
 3805            language_server_statuses: Default::default(),
 3806            nonce: StdRng::from_os_rng().random(),
 3807            diagnostic_summaries: HashMap::default(),
 3808            lsp_server_capabilities: HashMap::default(),
 3809            lsp_document_colors: HashMap::default(),
 3810            lsp_code_lens: HashMap::default(),
 3811            running_lsp_requests: HashMap::default(),
 3812            active_entry: None,
 3813
 3814            _maintain_workspace_config,
 3815            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3816        }
 3817    }
 3818
 3819    fn on_buffer_store_event(
 3820        &mut self,
 3821        _: Entity<BufferStore>,
 3822        event: &BufferStoreEvent,
 3823        cx: &mut Context<Self>,
 3824    ) {
 3825        match event {
 3826            BufferStoreEvent::BufferAdded(buffer) => {
 3827                self.on_buffer_added(buffer, cx).log_err();
 3828            }
 3829            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3830                let buffer_id = buffer.read(cx).remote_id();
 3831                if let Some(local) = self.as_local_mut()
 3832                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3833                {
 3834                    local.reset_buffer(buffer, old_file, cx);
 3835
 3836                    if local.registered_buffers.contains_key(&buffer_id) {
 3837                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3838                    }
 3839                }
 3840
 3841                self.detect_language_for_buffer(buffer, cx);
 3842                if let Some(local) = self.as_local_mut() {
 3843                    local.initialize_buffer(buffer, cx);
 3844                    if local.registered_buffers.contains_key(&buffer_id) {
 3845                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3846                    }
 3847                }
 3848            }
 3849            _ => {}
 3850        }
 3851    }
 3852
 3853    fn on_worktree_store_event(
 3854        &mut self,
 3855        _: Entity<WorktreeStore>,
 3856        event: &WorktreeStoreEvent,
 3857        cx: &mut Context<Self>,
 3858    ) {
 3859        match event {
 3860            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3861                if !worktree.read(cx).is_local() {
 3862                    return;
 3863                }
 3864                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3865                    worktree::Event::UpdatedEntries(changes) => {
 3866                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3867                    }
 3868                    worktree::Event::UpdatedGitRepositories(_)
 3869                    | worktree::Event::DeletedEntry(_) => {}
 3870                })
 3871                .detach()
 3872            }
 3873            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3874            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3875                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3876            }
 3877            WorktreeStoreEvent::WorktreeReleased(..)
 3878            | WorktreeStoreEvent::WorktreeOrderChanged
 3879            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3880            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3881            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3882        }
 3883    }
 3884
 3885    fn on_prettier_store_event(
 3886        &mut self,
 3887        _: Entity<PrettierStore>,
 3888        event: &PrettierStoreEvent,
 3889        cx: &mut Context<Self>,
 3890    ) {
 3891        match event {
 3892            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3893                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3894            }
 3895            PrettierStoreEvent::LanguageServerAdded {
 3896                new_server_id,
 3897                name,
 3898                prettier_server,
 3899            } => {
 3900                self.register_supplementary_language_server(
 3901                    *new_server_id,
 3902                    name.clone(),
 3903                    prettier_server.clone(),
 3904                    cx,
 3905                );
 3906            }
 3907        }
 3908    }
 3909
 3910    fn on_toolchain_store_event(
 3911        &mut self,
 3912        _: Entity<LocalToolchainStore>,
 3913        event: &ToolchainStoreEvent,
 3914        _: &mut Context<Self>,
 3915    ) {
 3916        if let ToolchainStoreEvent::ToolchainActivated = event {
 3917            self.request_workspace_config_refresh()
 3918        }
 3919    }
 3920
 3921    fn request_workspace_config_refresh(&mut self) {
 3922        *self._maintain_workspace_config.1.borrow_mut() = ();
 3923    }
 3924
 3925    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3926        self.as_local().map(|local| local.prettier_store.clone())
 3927    }
 3928
 3929    fn on_buffer_event(
 3930        &mut self,
 3931        buffer: Entity<Buffer>,
 3932        event: &language::BufferEvent,
 3933        cx: &mut Context<Self>,
 3934    ) {
 3935        match event {
 3936            language::BufferEvent::Edited => {
 3937                self.on_buffer_edited(buffer, cx);
 3938            }
 3939
 3940            language::BufferEvent::Saved => {
 3941                self.on_buffer_saved(buffer, cx);
 3942            }
 3943
 3944            _ => {}
 3945        }
 3946    }
 3947
 3948    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3949        buffer
 3950            .read(cx)
 3951            .set_language_registry(self.languages.clone());
 3952
 3953        cx.subscribe(buffer, |this, buffer, event, cx| {
 3954            this.on_buffer_event(buffer, event, cx);
 3955        })
 3956        .detach();
 3957
 3958        self.detect_language_for_buffer(buffer, cx);
 3959        if let Some(local) = self.as_local_mut() {
 3960            local.initialize_buffer(buffer, cx);
 3961        }
 3962
 3963        Ok(())
 3964    }
 3965
 3966    pub fn reload_zed_json_schemas_on_extensions_changed(
 3967        &mut self,
 3968        _: Entity<extension::ExtensionEvents>,
 3969        evt: &extension::Event,
 3970        cx: &mut Context<Self>,
 3971    ) {
 3972        match evt {
 3973            extension::Event::ExtensionInstalled(_)
 3974            | extension::Event::ExtensionUninstalled(_)
 3975            | extension::Event::ConfigureExtensionRequested(_) => return,
 3976            extension::Event::ExtensionsInstalledChanged => {}
 3977        }
 3978        if self.as_local().is_none() {
 3979            return;
 3980        }
 3981        cx.spawn(async move |this, cx| {
 3982            let weak_ref = this.clone();
 3983
 3984            let servers = this
 3985                .update(cx, |this, cx| {
 3986                    let local = this.as_local()?;
 3987
 3988                    let mut servers = Vec::new();
 3989                    for (seed, state) in &local.language_server_ids {
 3990
 3991                            let Some(states) = local.language_servers.get(&state.id) else {
 3992                                continue;
 3993                            };
 3994                            let (json_adapter, json_server) = match states {
 3995                                LanguageServerState::Running {
 3996                                    adapter, server, ..
 3997                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 3998                                    (adapter.adapter.clone(), server.clone())
 3999                                }
 4000                                _ => continue,
 4001                            };
 4002
 4003                            let Some(worktree) = this
 4004                                .worktree_store
 4005                                .read(cx)
 4006                                .worktree_for_id(seed.worktree_id, cx)
 4007                            else {
 4008                                continue;
 4009                            };
 4010                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4011                                LocalLspAdapterDelegate::new(
 4012                                    local.languages.clone(),
 4013                                    &local.environment,
 4014                                    weak_ref.clone(),
 4015                                    &worktree,
 4016                                    local.http_client.clone(),
 4017                                    local.fs.clone(),
 4018                                    cx,
 4019                                );
 4020
 4021                            servers.push((json_adapter, json_server, json_delegate));
 4022
 4023                    }
 4024                    Some(servers)
 4025                })
 4026                .ok()
 4027                .flatten();
 4028
 4029            let Some(servers) = servers else {
 4030                return;
 4031            };
 4032
 4033            for (adapter, server, delegate) in servers {
 4034                adapter.clear_zed_json_schema_cache().await;
 4035
 4036                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4037                        adapter,
 4038                        &delegate,
 4039                        None,
 4040                        cx,
 4041                    )
 4042                    .await
 4043                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4044                    .ok()
 4045                else {
 4046                    continue;
 4047                };
 4048                server
 4049                    .notify::<lsp::notification::DidChangeConfiguration>(
 4050                        &lsp::DidChangeConfigurationParams {
 4051                            settings: json_workspace_config,
 4052                        },
 4053                    )
 4054                    .ok();
 4055            }
 4056        })
 4057        .detach();
 4058    }
 4059
 4060    pub(crate) fn register_buffer_with_language_servers(
 4061        &mut self,
 4062        buffer: &Entity<Buffer>,
 4063        only_register_servers: HashSet<LanguageServerSelector>,
 4064        ignore_refcounts: bool,
 4065        cx: &mut Context<Self>,
 4066    ) -> OpenLspBufferHandle {
 4067        let buffer_id = buffer.read(cx).remote_id();
 4068        let handle = cx.new(|_| buffer.clone());
 4069        if let Some(local) = self.as_local_mut() {
 4070            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4071            if !ignore_refcounts {
 4072                *refcount += 1;
 4073            }
 4074
 4075            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4076            // 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
 4077            // 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
 4078            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4079            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4080                return handle;
 4081            };
 4082            if !file.is_local() {
 4083                return handle;
 4084            }
 4085
 4086            if ignore_refcounts || *refcount == 1 {
 4087                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4088            }
 4089            if !ignore_refcounts {
 4090                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4091                    let refcount = {
 4092                        let local = lsp_store.as_local_mut().unwrap();
 4093                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4094                            debug_panic!("bad refcounting");
 4095                            return;
 4096                        };
 4097
 4098                        *refcount -= 1;
 4099                        *refcount
 4100                    };
 4101                    if refcount == 0 {
 4102                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4103                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4104                        let local = lsp_store.as_local_mut().unwrap();
 4105                        local.registered_buffers.remove(&buffer_id);
 4106                        local.buffers_opened_in_servers.remove(&buffer_id);
 4107                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4108                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4109                        }
 4110                    }
 4111                })
 4112                .detach();
 4113            }
 4114        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4115            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4116            cx.background_spawn(async move {
 4117                upstream_client
 4118                    .request(proto::RegisterBufferWithLanguageServers {
 4119                        project_id: upstream_project_id,
 4120                        buffer_id,
 4121                        only_servers: only_register_servers
 4122                            .into_iter()
 4123                            .map(|selector| {
 4124                                let selector = match selector {
 4125                                    LanguageServerSelector::Id(language_server_id) => {
 4126                                        proto::language_server_selector::Selector::ServerId(
 4127                                            language_server_id.to_proto(),
 4128                                        )
 4129                                    }
 4130                                    LanguageServerSelector::Name(language_server_name) => {
 4131                                        proto::language_server_selector::Selector::Name(
 4132                                            language_server_name.to_string(),
 4133                                        )
 4134                                    }
 4135                                };
 4136                                proto::LanguageServerSelector {
 4137                                    selector: Some(selector),
 4138                                }
 4139                            })
 4140                            .collect(),
 4141                    })
 4142                    .await
 4143            })
 4144            .detach();
 4145        } else {
 4146            panic!("oops!");
 4147        }
 4148        handle
 4149    }
 4150
 4151    fn maintain_buffer_languages(
 4152        languages: Arc<LanguageRegistry>,
 4153        cx: &mut Context<Self>,
 4154    ) -> Task<()> {
 4155        let mut subscription = languages.subscribe();
 4156        let mut prev_reload_count = languages.reload_count();
 4157        cx.spawn(async move |this, cx| {
 4158            while let Some(()) = subscription.next().await {
 4159                if let Some(this) = this.upgrade() {
 4160                    // If the language registry has been reloaded, then remove and
 4161                    // re-assign the languages on all open buffers.
 4162                    let reload_count = languages.reload_count();
 4163                    if reload_count > prev_reload_count {
 4164                        prev_reload_count = reload_count;
 4165                        this.update(cx, |this, cx| {
 4166                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4167                                for buffer in buffer_store.buffers() {
 4168                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4169                                    {
 4170                                        buffer
 4171                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4172                                        if let Some(local) = this.as_local_mut() {
 4173                                            local.reset_buffer(&buffer, &f, cx);
 4174
 4175                                            if local
 4176                                                .registered_buffers
 4177                                                .contains_key(&buffer.read(cx).remote_id())
 4178                                                && let Some(file_url) =
 4179                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4180                                            {
 4181                                                local.unregister_buffer_from_language_servers(
 4182                                                    &buffer, &file_url, cx,
 4183                                                );
 4184                                            }
 4185                                        }
 4186                                    }
 4187                                }
 4188                            });
 4189                        })
 4190                        .ok();
 4191                    }
 4192
 4193                    this.update(cx, |this, cx| {
 4194                        let mut plain_text_buffers = Vec::new();
 4195                        let mut buffers_with_unknown_injections = Vec::new();
 4196                        for handle in this.buffer_store.read(cx).buffers() {
 4197                            let buffer = handle.read(cx);
 4198                            if buffer.language().is_none()
 4199                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4200                            {
 4201                                plain_text_buffers.push(handle);
 4202                            } else if buffer.contains_unknown_injections() {
 4203                                buffers_with_unknown_injections.push(handle);
 4204                            }
 4205                        }
 4206
 4207                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4208                        // and reused later in the invisible worktrees.
 4209                        plain_text_buffers.sort_by_key(|buffer| {
 4210                            Reverse(
 4211                                File::from_dyn(buffer.read(cx).file())
 4212                                    .map(|file| file.worktree.read(cx).is_visible()),
 4213                            )
 4214                        });
 4215
 4216                        for buffer in plain_text_buffers {
 4217                            this.detect_language_for_buffer(&buffer, cx);
 4218                            if let Some(local) = this.as_local_mut() {
 4219                                local.initialize_buffer(&buffer, cx);
 4220                                if local
 4221                                    .registered_buffers
 4222                                    .contains_key(&buffer.read(cx).remote_id())
 4223                                {
 4224                                    local.register_buffer_with_language_servers(
 4225                                        &buffer,
 4226                                        HashSet::default(),
 4227                                        cx,
 4228                                    );
 4229                                }
 4230                            }
 4231                        }
 4232
 4233                        for buffer in buffers_with_unknown_injections {
 4234                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4235                        }
 4236                    })
 4237                    .ok();
 4238                }
 4239            }
 4240        })
 4241    }
 4242
 4243    fn detect_language_for_buffer(
 4244        &mut self,
 4245        buffer_handle: &Entity<Buffer>,
 4246        cx: &mut Context<Self>,
 4247    ) -> Option<language::AvailableLanguage> {
 4248        // If the buffer has a language, set it and start the language server if we haven't already.
 4249        let buffer = buffer_handle.read(cx);
 4250        let file = buffer.file()?;
 4251
 4252        let content = buffer.as_rope();
 4253        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4254        if let Some(available_language) = &available_language {
 4255            if let Some(Ok(Ok(new_language))) = self
 4256                .languages
 4257                .load_language(available_language)
 4258                .now_or_never()
 4259            {
 4260                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4261            }
 4262        } else {
 4263            cx.emit(LspStoreEvent::LanguageDetected {
 4264                buffer: buffer_handle.clone(),
 4265                new_language: None,
 4266            });
 4267        }
 4268
 4269        available_language
 4270    }
 4271
 4272    pub(crate) fn set_language_for_buffer(
 4273        &mut self,
 4274        buffer_entity: &Entity<Buffer>,
 4275        new_language: Arc<Language>,
 4276        cx: &mut Context<Self>,
 4277    ) {
 4278        let buffer = buffer_entity.read(cx);
 4279        let buffer_file = buffer.file().cloned();
 4280        let buffer_id = buffer.remote_id();
 4281        if let Some(local_store) = self.as_local_mut()
 4282            && local_store.registered_buffers.contains_key(&buffer_id)
 4283            && let Some(abs_path) =
 4284                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4285            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4286        {
 4287            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4288        }
 4289        buffer_entity.update(cx, |buffer, cx| {
 4290            if buffer
 4291                .language()
 4292                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4293            {
 4294                buffer.set_language(Some(new_language.clone()), cx);
 4295            }
 4296        });
 4297
 4298        let settings =
 4299            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4300        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4301
 4302        let worktree_id = if let Some(file) = buffer_file {
 4303            let worktree = file.worktree.clone();
 4304
 4305            if let Some(local) = self.as_local_mut()
 4306                && local.registered_buffers.contains_key(&buffer_id)
 4307            {
 4308                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4309            }
 4310            Some(worktree.read(cx).id())
 4311        } else {
 4312            None
 4313        };
 4314
 4315        if settings.prettier.allowed
 4316            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4317        {
 4318            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4319            if let Some(prettier_store) = prettier_store {
 4320                prettier_store.update(cx, |prettier_store, cx| {
 4321                    prettier_store.install_default_prettier(
 4322                        worktree_id,
 4323                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4324                        cx,
 4325                    )
 4326                })
 4327            }
 4328        }
 4329
 4330        cx.emit(LspStoreEvent::LanguageDetected {
 4331            buffer: buffer_entity.clone(),
 4332            new_language: Some(new_language),
 4333        })
 4334    }
 4335
 4336    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4337        self.buffer_store.clone()
 4338    }
 4339
 4340    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4341        self.active_entry = active_entry;
 4342    }
 4343
 4344    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4345        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4346            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4347        {
 4348            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4349                summaries
 4350                    .iter()
 4351                    .map(|(server_id, summary)| summary.to_proto(*server_id, path))
 4352            });
 4353            if let Some(summary) = summaries.next() {
 4354                client
 4355                    .send(proto::UpdateDiagnosticSummary {
 4356                        project_id: downstream_project_id,
 4357                        worktree_id: worktree.id().to_proto(),
 4358                        summary: Some(summary),
 4359                        more_summaries: summaries.collect(),
 4360                    })
 4361                    .log_err();
 4362            }
 4363        }
 4364    }
 4365
 4366    fn is_capable_for_proto_request<R>(
 4367        &self,
 4368        buffer: &Entity<Buffer>,
 4369        request: &R,
 4370        cx: &Context<Self>,
 4371    ) -> bool
 4372    where
 4373        R: LspCommand,
 4374    {
 4375        self.check_if_capable_for_proto_request(
 4376            buffer,
 4377            |capabilities| {
 4378                request.check_capabilities(AdapterServerCapabilities {
 4379                    server_capabilities: capabilities.clone(),
 4380                    code_action_kinds: None,
 4381                })
 4382            },
 4383            cx,
 4384        )
 4385    }
 4386
 4387    fn check_if_capable_for_proto_request<F>(
 4388        &self,
 4389        buffer: &Entity<Buffer>,
 4390        check: F,
 4391        cx: &Context<Self>,
 4392    ) -> bool
 4393    where
 4394        F: Fn(&lsp::ServerCapabilities) -> bool,
 4395    {
 4396        let Some(language) = buffer.read(cx).language().cloned() else {
 4397            return false;
 4398        };
 4399        let relevant_language_servers = self
 4400            .languages
 4401            .lsp_adapters(&language.name())
 4402            .into_iter()
 4403            .map(|lsp_adapter| lsp_adapter.name())
 4404            .collect::<HashSet<_>>();
 4405        self.language_server_statuses
 4406            .iter()
 4407            .filter_map(|(server_id, server_status)| {
 4408                relevant_language_servers
 4409                    .contains(&server_status.name)
 4410                    .then_some(server_id)
 4411            })
 4412            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4413            .any(check)
 4414    }
 4415
 4416    pub fn request_lsp<R>(
 4417        &mut self,
 4418        buffer: Entity<Buffer>,
 4419        server: LanguageServerToQuery,
 4420        request: R,
 4421        cx: &mut Context<Self>,
 4422    ) -> Task<Result<R::Response>>
 4423    where
 4424        R: LspCommand,
 4425        <R::LspRequest as lsp::request::Request>::Result: Send,
 4426        <R::LspRequest as lsp::request::Request>::Params: Send,
 4427    {
 4428        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4429            return self.send_lsp_proto_request(
 4430                buffer,
 4431                upstream_client,
 4432                upstream_project_id,
 4433                request,
 4434                cx,
 4435            );
 4436        }
 4437
 4438        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4439            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4440                local
 4441                    .language_servers_for_buffer(buffer, cx)
 4442                    .find(|(_, server)| {
 4443                        request.check_capabilities(server.adapter_server_capabilities())
 4444                    })
 4445                    .map(|(_, server)| server.clone())
 4446            }),
 4447            LanguageServerToQuery::Other(id) => self
 4448                .language_server_for_local_buffer(buffer, id, cx)
 4449                .and_then(|(_, server)| {
 4450                    request
 4451                        .check_capabilities(server.adapter_server_capabilities())
 4452                        .then(|| Arc::clone(server))
 4453                }),
 4454        }) else {
 4455            return Task::ready(Ok(Default::default()));
 4456        };
 4457
 4458        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4459
 4460        let Some(file) = file else {
 4461            return Task::ready(Ok(Default::default()));
 4462        };
 4463
 4464        let lsp_params = match request.to_lsp_params_or_response(
 4465            &file.abs_path(cx),
 4466            buffer.read(cx),
 4467            &language_server,
 4468            cx,
 4469        ) {
 4470            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4471            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4472
 4473            Err(err) => {
 4474                let message = format!(
 4475                    "{} via {} failed: {}",
 4476                    request.display_name(),
 4477                    language_server.name(),
 4478                    err
 4479                );
 4480                log::warn!("{message}");
 4481                return Task::ready(Err(anyhow!(message)));
 4482            }
 4483        };
 4484
 4485        let status = request.status();
 4486        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4487            return Task::ready(Ok(Default::default()));
 4488        }
 4489        cx.spawn(async move |this, cx| {
 4490            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4491
 4492            let id = lsp_request.id();
 4493            let _cleanup = if status.is_some() {
 4494                cx.update(|cx| {
 4495                    this.update(cx, |this, cx| {
 4496                        this.on_lsp_work_start(
 4497                            language_server.server_id(),
 4498                            id.to_string(),
 4499                            LanguageServerProgress {
 4500                                is_disk_based_diagnostics_progress: false,
 4501                                is_cancellable: false,
 4502                                title: None,
 4503                                message: status.clone(),
 4504                                percentage: None,
 4505                                last_update_at: cx.background_executor().now(),
 4506                            },
 4507                            cx,
 4508                        );
 4509                    })
 4510                })
 4511                .log_err();
 4512
 4513                Some(defer(|| {
 4514                    cx.update(|cx| {
 4515                        this.update(cx, |this, cx| {
 4516                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4517                        })
 4518                    })
 4519                    .log_err();
 4520                }))
 4521            } else {
 4522                None
 4523            };
 4524
 4525            let result = lsp_request.await.into_response();
 4526
 4527            let response = result.map_err(|err| {
 4528                let message = format!(
 4529                    "{} via {} failed: {}",
 4530                    request.display_name(),
 4531                    language_server.name(),
 4532                    err
 4533                );
 4534                log::warn!("{message}");
 4535                anyhow::anyhow!(message)
 4536            })?;
 4537
 4538            request
 4539                .response_from_lsp(
 4540                    response,
 4541                    this.upgrade().context("no app context")?,
 4542                    buffer,
 4543                    language_server.server_id(),
 4544                    cx.clone(),
 4545                )
 4546                .await
 4547        })
 4548    }
 4549
 4550    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4551        let mut language_formatters_to_check = Vec::new();
 4552        for buffer in self.buffer_store.read(cx).buffers() {
 4553            let buffer = buffer.read(cx);
 4554            let buffer_file = File::from_dyn(buffer.file());
 4555            let buffer_language = buffer.language();
 4556            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4557            if buffer_language.is_some() {
 4558                language_formatters_to_check.push((
 4559                    buffer_file.map(|f| f.worktree_id(cx)),
 4560                    settings.into_owned(),
 4561                ));
 4562            }
 4563        }
 4564
 4565        self.request_workspace_config_refresh();
 4566
 4567        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4568            prettier_store.update(cx, |prettier_store, cx| {
 4569                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4570            })
 4571        }
 4572
 4573        cx.notify();
 4574    }
 4575
 4576    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4577        let buffer_store = self.buffer_store.clone();
 4578        let Some(local) = self.as_local_mut() else {
 4579            return;
 4580        };
 4581        let mut adapters = BTreeMap::default();
 4582        let get_adapter = {
 4583            let languages = local.languages.clone();
 4584            let environment = local.environment.clone();
 4585            let weak = local.weak.clone();
 4586            let worktree_store = local.worktree_store.clone();
 4587            let http_client = local.http_client.clone();
 4588            let fs = local.fs.clone();
 4589            move |worktree_id, cx: &mut App| {
 4590                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4591                Some(LocalLspAdapterDelegate::new(
 4592                    languages.clone(),
 4593                    &environment,
 4594                    weak.clone(),
 4595                    &worktree,
 4596                    http_client.clone(),
 4597                    fs.clone(),
 4598                    cx,
 4599                ))
 4600            }
 4601        };
 4602
 4603        let mut messages_to_report = Vec::new();
 4604        let (new_tree, to_stop) = {
 4605            let mut rebase = local.lsp_tree.rebase();
 4606            let buffers = buffer_store
 4607                .read(cx)
 4608                .buffers()
 4609                .filter_map(|buffer| {
 4610                    let raw_buffer = buffer.read(cx);
 4611                    if !local
 4612                        .registered_buffers
 4613                        .contains_key(&raw_buffer.remote_id())
 4614                    {
 4615                        return None;
 4616                    }
 4617                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4618                    let language = raw_buffer.language().cloned()?;
 4619                    Some((file, language, raw_buffer.remote_id()))
 4620                })
 4621                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4622            for (file, language, buffer_id) in buffers {
 4623                let worktree_id = file.worktree_id(cx);
 4624                let Some(worktree) = local
 4625                    .worktree_store
 4626                    .read(cx)
 4627                    .worktree_for_id(worktree_id, cx)
 4628                else {
 4629                    continue;
 4630                };
 4631
 4632                if let Some((_, apply)) = local.reuse_existing_language_server(
 4633                    rebase.server_tree(),
 4634                    &worktree,
 4635                    &language.name(),
 4636                    cx,
 4637                ) {
 4638                    (apply)(rebase.server_tree());
 4639                } else if let Some(lsp_delegate) = adapters
 4640                    .entry(worktree_id)
 4641                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4642                    .clone()
 4643                {
 4644                    let delegate =
 4645                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4646                    let path = file
 4647                        .path()
 4648                        .parent()
 4649                        .map(Arc::from)
 4650                        .unwrap_or_else(|| file.path().clone());
 4651                    let worktree_path = ProjectPath { worktree_id, path };
 4652                    let abs_path = file.abs_path(cx);
 4653                    let worktree_root = worktree.read(cx).abs_path();
 4654                    let nodes = rebase
 4655                        .walk(
 4656                            worktree_path,
 4657                            language.name(),
 4658                            language.manifest(),
 4659                            delegate.clone(),
 4660                            cx,
 4661                        )
 4662                        .collect::<Vec<_>>();
 4663                    for node in nodes {
 4664                        let server_id = node.server_id_or_init(|disposition| {
 4665                            let path = &disposition.path;
 4666                            let uri = Uri::from_file_path(worktree_root.join(&path.path));
 4667                            let key = LanguageServerSeed {
 4668                                worktree_id,
 4669                                name: disposition.server_name.clone(),
 4670                                settings: disposition.settings.clone(),
 4671                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4672                                    path.worktree_id,
 4673                                    &path.path,
 4674                                    language.name(),
 4675                                ),
 4676                            };
 4677                            local.language_server_ids.remove(&key);
 4678
 4679                            let server_id = local.get_or_insert_language_server(
 4680                                &worktree,
 4681                                lsp_delegate.clone(),
 4682                                disposition,
 4683                                &language.name(),
 4684                                cx,
 4685                            );
 4686                            if let Some(state) = local.language_servers.get(&server_id)
 4687                                && let Ok(uri) = uri
 4688                            {
 4689                                state.add_workspace_folder(uri);
 4690                            };
 4691                            server_id
 4692                        });
 4693
 4694                        if let Some(language_server_id) = server_id {
 4695                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4696                                language_server_id,
 4697                                name: node.name(),
 4698                                message:
 4699                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4700                                        proto::RegisteredForBuffer {
 4701                                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 4702                                            buffer_id: buffer_id.to_proto(),
 4703                                        },
 4704                                    ),
 4705                            });
 4706                        }
 4707                    }
 4708                } else {
 4709                    continue;
 4710                }
 4711            }
 4712            rebase.finish()
 4713        };
 4714        for message in messages_to_report {
 4715            cx.emit(message);
 4716        }
 4717        local.lsp_tree = new_tree;
 4718        for (id, _) in to_stop {
 4719            self.stop_local_language_server(id, cx).detach();
 4720        }
 4721    }
 4722
 4723    pub fn apply_code_action(
 4724        &self,
 4725        buffer_handle: Entity<Buffer>,
 4726        mut action: CodeAction,
 4727        push_to_history: bool,
 4728        cx: &mut Context<Self>,
 4729    ) -> Task<Result<ProjectTransaction>> {
 4730        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4731            let request = proto::ApplyCodeAction {
 4732                project_id,
 4733                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4734                action: Some(Self::serialize_code_action(&action)),
 4735            };
 4736            let buffer_store = self.buffer_store();
 4737            cx.spawn(async move |_, cx| {
 4738                let response = upstream_client
 4739                    .request(request)
 4740                    .await?
 4741                    .transaction
 4742                    .context("missing transaction")?;
 4743
 4744                buffer_store
 4745                    .update(cx, |buffer_store, cx| {
 4746                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4747                    })?
 4748                    .await
 4749            })
 4750        } else if self.mode.is_local() {
 4751            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4752                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4753                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4754            }) else {
 4755                return Task::ready(Ok(ProjectTransaction::default()));
 4756            };
 4757            cx.spawn(async move |this,  cx| {
 4758                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4759                    .await
 4760                    .context("resolving a code action")?;
 4761                if let Some(edit) = action.lsp_action.edit()
 4762                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4763                        return LocalLspStore::deserialize_workspace_edit(
 4764                            this.upgrade().context("no app present")?,
 4765                            edit.clone(),
 4766                            push_to_history,
 4767
 4768                            lang_server.clone(),
 4769                            cx,
 4770                        )
 4771                        .await;
 4772                    }
 4773
 4774                if let Some(command) = action.lsp_action.command() {
 4775                    let server_capabilities = lang_server.capabilities();
 4776                    let available_commands = server_capabilities
 4777                        .execute_command_provider
 4778                        .as_ref()
 4779                        .map(|options| options.commands.as_slice())
 4780                        .unwrap_or_default();
 4781                    if available_commands.contains(&command.command) {
 4782                        this.update(cx, |this, _| {
 4783                            this.as_local_mut()
 4784                                .unwrap()
 4785                                .last_workspace_edits_by_language_server
 4786                                .remove(&lang_server.server_id());
 4787                        })?;
 4788
 4789                        let _result = lang_server
 4790                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4791                                command: command.command.clone(),
 4792                                arguments: command.arguments.clone().unwrap_or_default(),
 4793                                ..lsp::ExecuteCommandParams::default()
 4794                            })
 4795                            .await.into_response()
 4796                            .context("execute command")?;
 4797
 4798                        return this.update(cx, |this, _| {
 4799                            this.as_local_mut()
 4800                                .unwrap()
 4801                                .last_workspace_edits_by_language_server
 4802                                .remove(&lang_server.server_id())
 4803                                .unwrap_or_default()
 4804                        });
 4805                    } else {
 4806                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4807                    }
 4808                }
 4809
 4810                Ok(ProjectTransaction::default())
 4811            })
 4812        } else {
 4813            Task::ready(Err(anyhow!("no upstream client and not local")))
 4814        }
 4815    }
 4816
 4817    pub fn apply_code_action_kind(
 4818        &mut self,
 4819        buffers: HashSet<Entity<Buffer>>,
 4820        kind: CodeActionKind,
 4821        push_to_history: bool,
 4822        cx: &mut Context<Self>,
 4823    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4824        if self.as_local().is_some() {
 4825            cx.spawn(async move |lsp_store, cx| {
 4826                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4827                let result = LocalLspStore::execute_code_action_kind_locally(
 4828                    lsp_store.clone(),
 4829                    buffers,
 4830                    kind,
 4831                    push_to_history,
 4832                    cx,
 4833                )
 4834                .await;
 4835                lsp_store.update(cx, |lsp_store, _| {
 4836                    lsp_store.update_last_formatting_failure(&result);
 4837                })?;
 4838                result
 4839            })
 4840        } else if let Some((client, project_id)) = self.upstream_client() {
 4841            let buffer_store = self.buffer_store();
 4842            cx.spawn(async move |lsp_store, cx| {
 4843                let result = client
 4844                    .request(proto::ApplyCodeActionKind {
 4845                        project_id,
 4846                        kind: kind.as_str().to_owned(),
 4847                        buffer_ids: buffers
 4848                            .iter()
 4849                            .map(|buffer| {
 4850                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4851                            })
 4852                            .collect::<Result<_>>()?,
 4853                    })
 4854                    .await
 4855                    .and_then(|result| result.transaction.context("missing transaction"));
 4856                lsp_store.update(cx, |lsp_store, _| {
 4857                    lsp_store.update_last_formatting_failure(&result);
 4858                })?;
 4859
 4860                let transaction_response = result?;
 4861                buffer_store
 4862                    .update(cx, |buffer_store, cx| {
 4863                        buffer_store.deserialize_project_transaction(
 4864                            transaction_response,
 4865                            push_to_history,
 4866                            cx,
 4867                        )
 4868                    })?
 4869                    .await
 4870            })
 4871        } else {
 4872            Task::ready(Ok(ProjectTransaction::default()))
 4873        }
 4874    }
 4875
 4876    pub fn resolve_inlay_hint(
 4877        &self,
 4878        mut hint: InlayHint,
 4879        buffer: Entity<Buffer>,
 4880        server_id: LanguageServerId,
 4881        cx: &mut Context<Self>,
 4882    ) -> Task<anyhow::Result<InlayHint>> {
 4883        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4884            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4885            {
 4886                hint.resolve_state = ResolveState::Resolved;
 4887                return Task::ready(Ok(hint));
 4888            }
 4889            let request = proto::ResolveInlayHint {
 4890                project_id,
 4891                buffer_id: buffer.read(cx).remote_id().into(),
 4892                language_server_id: server_id.0 as u64,
 4893                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4894            };
 4895            cx.background_spawn(async move {
 4896                let response = upstream_client
 4897                    .request(request)
 4898                    .await
 4899                    .context("inlay hints proto request")?;
 4900                match response.hint {
 4901                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4902                        .context("inlay hints proto resolve response conversion"),
 4903                    None => Ok(hint),
 4904                }
 4905            })
 4906        } else {
 4907            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4908                self.language_server_for_local_buffer(buffer, server_id, cx)
 4909                    .map(|(_, server)| server.clone())
 4910            }) else {
 4911                return Task::ready(Ok(hint));
 4912            };
 4913            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4914                return Task::ready(Ok(hint));
 4915            }
 4916            let buffer_snapshot = buffer.read(cx).snapshot();
 4917            cx.spawn(async move |_, cx| {
 4918                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4919                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4920                );
 4921                let resolved_hint = resolve_task
 4922                    .await
 4923                    .into_response()
 4924                    .context("inlay hint resolve LSP request")?;
 4925                let resolved_hint = InlayHints::lsp_to_project_hint(
 4926                    resolved_hint,
 4927                    &buffer,
 4928                    server_id,
 4929                    ResolveState::Resolved,
 4930                    false,
 4931                    cx,
 4932                )
 4933                .await?;
 4934                Ok(resolved_hint)
 4935            })
 4936        }
 4937    }
 4938
 4939    pub fn resolve_color_presentation(
 4940        &mut self,
 4941        mut color: DocumentColor,
 4942        buffer: Entity<Buffer>,
 4943        server_id: LanguageServerId,
 4944        cx: &mut Context<Self>,
 4945    ) -> Task<Result<DocumentColor>> {
 4946        if color.resolved {
 4947            return Task::ready(Ok(color));
 4948        }
 4949
 4950        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4951            let start = color.lsp_range.start;
 4952            let end = color.lsp_range.end;
 4953            let request = proto::GetColorPresentation {
 4954                project_id,
 4955                server_id: server_id.to_proto(),
 4956                buffer_id: buffer.read(cx).remote_id().into(),
 4957                color: Some(proto::ColorInformation {
 4958                    red: color.color.red,
 4959                    green: color.color.green,
 4960                    blue: color.color.blue,
 4961                    alpha: color.color.alpha,
 4962                    lsp_range_start: Some(proto::PointUtf16 {
 4963                        row: start.line,
 4964                        column: start.character,
 4965                    }),
 4966                    lsp_range_end: Some(proto::PointUtf16 {
 4967                        row: end.line,
 4968                        column: end.character,
 4969                    }),
 4970                }),
 4971            };
 4972            cx.background_spawn(async move {
 4973                let response = upstream_client
 4974                    .request(request)
 4975                    .await
 4976                    .context("color presentation proto request")?;
 4977                color.resolved = true;
 4978                color.color_presentations = response
 4979                    .presentations
 4980                    .into_iter()
 4981                    .map(|presentation| ColorPresentation {
 4982                        label: SharedString::from(presentation.label),
 4983                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 4984                        additional_text_edits: presentation
 4985                            .additional_text_edits
 4986                            .into_iter()
 4987                            .filter_map(deserialize_lsp_edit)
 4988                            .collect(),
 4989                    })
 4990                    .collect();
 4991                Ok(color)
 4992            })
 4993        } else {
 4994            let path = match buffer
 4995                .update(cx, |buffer, cx| {
 4996                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 4997                })
 4998                .context("buffer with the missing path")
 4999            {
 5000                Ok(path) => path,
 5001                Err(e) => return Task::ready(Err(e)),
 5002            };
 5003            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5004                self.language_server_for_local_buffer(buffer, server_id, cx)
 5005                    .map(|(_, server)| server.clone())
 5006            }) else {
 5007                return Task::ready(Ok(color));
 5008            };
 5009            cx.background_spawn(async move {
 5010                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5011                    lsp::ColorPresentationParams {
 5012                        text_document: make_text_document_identifier(&path)?,
 5013                        color: color.color,
 5014                        range: color.lsp_range,
 5015                        work_done_progress_params: Default::default(),
 5016                        partial_result_params: Default::default(),
 5017                    },
 5018                );
 5019                color.color_presentations = resolve_task
 5020                    .await
 5021                    .into_response()
 5022                    .context("color presentation resolve LSP request")?
 5023                    .into_iter()
 5024                    .map(|presentation| ColorPresentation {
 5025                        label: SharedString::from(presentation.label),
 5026                        text_edit: presentation.text_edit,
 5027                        additional_text_edits: presentation
 5028                            .additional_text_edits
 5029                            .unwrap_or_default(),
 5030                    })
 5031                    .collect();
 5032                color.resolved = true;
 5033                Ok(color)
 5034            })
 5035        }
 5036    }
 5037
 5038    pub(crate) fn linked_edits(
 5039        &mut self,
 5040        buffer: &Entity<Buffer>,
 5041        position: Anchor,
 5042        cx: &mut Context<Self>,
 5043    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5044        let snapshot = buffer.read(cx).snapshot();
 5045        let scope = snapshot.language_scope_at(position);
 5046        let Some(server_id) = self
 5047            .as_local()
 5048            .and_then(|local| {
 5049                buffer.update(cx, |buffer, cx| {
 5050                    local
 5051                        .language_servers_for_buffer(buffer, cx)
 5052                        .filter(|(_, server)| {
 5053                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5054                        })
 5055                        .filter(|(adapter, _)| {
 5056                            scope
 5057                                .as_ref()
 5058                                .map(|scope| scope.language_allowed(&adapter.name))
 5059                                .unwrap_or(true)
 5060                        })
 5061                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5062                        .next()
 5063                })
 5064            })
 5065            .or_else(|| {
 5066                self.upstream_client()
 5067                    .is_some()
 5068                    .then_some(LanguageServerToQuery::FirstCapable)
 5069            })
 5070            .filter(|_| {
 5071                maybe!({
 5072                    let language = buffer.read(cx).language_at(position)?;
 5073                    Some(
 5074                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5075                            .linked_edits,
 5076                    )
 5077                }) == Some(true)
 5078            })
 5079        else {
 5080            return Task::ready(Ok(Vec::new()));
 5081        };
 5082
 5083        self.request_lsp(
 5084            buffer.clone(),
 5085            server_id,
 5086            LinkedEditingRange { position },
 5087            cx,
 5088        )
 5089    }
 5090
 5091    fn apply_on_type_formatting(
 5092        &mut self,
 5093        buffer: Entity<Buffer>,
 5094        position: Anchor,
 5095        trigger: String,
 5096        cx: &mut Context<Self>,
 5097    ) -> Task<Result<Option<Transaction>>> {
 5098        if let Some((client, project_id)) = self.upstream_client() {
 5099            if !self.check_if_capable_for_proto_request(
 5100                &buffer,
 5101                |capabilities| {
 5102                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5103                },
 5104                cx,
 5105            ) {
 5106                return Task::ready(Ok(None));
 5107            }
 5108            let request = proto::OnTypeFormatting {
 5109                project_id,
 5110                buffer_id: buffer.read(cx).remote_id().into(),
 5111                position: Some(serialize_anchor(&position)),
 5112                trigger,
 5113                version: serialize_version(&buffer.read(cx).version()),
 5114            };
 5115            cx.background_spawn(async move {
 5116                client
 5117                    .request(request)
 5118                    .await?
 5119                    .transaction
 5120                    .map(language::proto::deserialize_transaction)
 5121                    .transpose()
 5122            })
 5123        } else if let Some(local) = self.as_local_mut() {
 5124            let buffer_id = buffer.read(cx).remote_id();
 5125            local.buffers_being_formatted.insert(buffer_id);
 5126            cx.spawn(async move |this, cx| {
 5127                let _cleanup = defer({
 5128                    let this = this.clone();
 5129                    let mut cx = cx.clone();
 5130                    move || {
 5131                        this.update(&mut cx, |this, _| {
 5132                            if let Some(local) = this.as_local_mut() {
 5133                                local.buffers_being_formatted.remove(&buffer_id);
 5134                            }
 5135                        })
 5136                        .ok();
 5137                    }
 5138                });
 5139
 5140                buffer
 5141                    .update(cx, |buffer, _| {
 5142                        buffer.wait_for_edits(Some(position.timestamp))
 5143                    })?
 5144                    .await?;
 5145                this.update(cx, |this, cx| {
 5146                    let position = position.to_point_utf16(buffer.read(cx));
 5147                    this.on_type_format(buffer, position, trigger, false, cx)
 5148                })?
 5149                .await
 5150            })
 5151        } else {
 5152            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5153        }
 5154    }
 5155
 5156    pub fn on_type_format<T: ToPointUtf16>(
 5157        &mut self,
 5158        buffer: Entity<Buffer>,
 5159        position: T,
 5160        trigger: String,
 5161        push_to_history: bool,
 5162        cx: &mut Context<Self>,
 5163    ) -> Task<Result<Option<Transaction>>> {
 5164        let position = position.to_point_utf16(buffer.read(cx));
 5165        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5166    }
 5167
 5168    fn on_type_format_impl(
 5169        &mut self,
 5170        buffer: Entity<Buffer>,
 5171        position: PointUtf16,
 5172        trigger: String,
 5173        push_to_history: bool,
 5174        cx: &mut Context<Self>,
 5175    ) -> Task<Result<Option<Transaction>>> {
 5176        let options = buffer.update(cx, |buffer, cx| {
 5177            lsp_command::lsp_formatting_options(
 5178                language_settings(
 5179                    buffer.language_at(position).map(|l| l.name()),
 5180                    buffer.file(),
 5181                    cx,
 5182                )
 5183                .as_ref(),
 5184            )
 5185        });
 5186
 5187        cx.spawn(async move |this, cx| {
 5188            if let Some(waiter) =
 5189                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5190            {
 5191                waiter.await?;
 5192            }
 5193            cx.update(|cx| {
 5194                this.update(cx, |this, cx| {
 5195                    this.request_lsp(
 5196                        buffer.clone(),
 5197                        LanguageServerToQuery::FirstCapable,
 5198                        OnTypeFormatting {
 5199                            position,
 5200                            trigger,
 5201                            options,
 5202                            push_to_history,
 5203                        },
 5204                        cx,
 5205                    )
 5206                })
 5207            })??
 5208            .await
 5209        })
 5210    }
 5211
 5212    pub fn definitions(
 5213        &mut self,
 5214        buffer: &Entity<Buffer>,
 5215        position: PointUtf16,
 5216        cx: &mut Context<Self>,
 5217    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5218        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5219            let request = GetDefinitions { position };
 5220            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5221                return Task::ready(Ok(None));
 5222            }
 5223            let request_task = upstream_client.request_lsp(
 5224                project_id,
 5225                LSP_REQUEST_TIMEOUT,
 5226                cx.background_executor().clone(),
 5227                request.to_proto(project_id, buffer.read(cx)),
 5228            );
 5229            let buffer = buffer.clone();
 5230            cx.spawn(async move |weak_project, cx| {
 5231                let Some(project) = weak_project.upgrade() else {
 5232                    return Ok(None);
 5233                };
 5234                let Some(responses) = request_task.await? else {
 5235                    return Ok(None);
 5236                };
 5237                let actions = join_all(responses.payload.into_iter().map(|response| {
 5238                    GetDefinitions { position }.response_from_proto(
 5239                        response.response,
 5240                        project.clone(),
 5241                        buffer.clone(),
 5242                        cx.clone(),
 5243                    )
 5244                }))
 5245                .await;
 5246
 5247                Ok(Some(
 5248                    actions
 5249                        .into_iter()
 5250                        .collect::<Result<Vec<Vec<_>>>>()?
 5251                        .into_iter()
 5252                        .flatten()
 5253                        .dedup()
 5254                        .collect(),
 5255                ))
 5256            })
 5257        } else {
 5258            let definitions_task = self.request_multiple_lsp_locally(
 5259                buffer,
 5260                Some(position),
 5261                GetDefinitions { position },
 5262                cx,
 5263            );
 5264            cx.background_spawn(async move {
 5265                Ok(Some(
 5266                    definitions_task
 5267                        .await
 5268                        .into_iter()
 5269                        .flat_map(|(_, definitions)| definitions)
 5270                        .dedup()
 5271                        .collect(),
 5272                ))
 5273            })
 5274        }
 5275    }
 5276
 5277    pub fn declarations(
 5278        &mut self,
 5279        buffer: &Entity<Buffer>,
 5280        position: PointUtf16,
 5281        cx: &mut Context<Self>,
 5282    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5283        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5284            let request = GetDeclarations { position };
 5285            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5286                return Task::ready(Ok(None));
 5287            }
 5288            let request_task = upstream_client.request_lsp(
 5289                project_id,
 5290                LSP_REQUEST_TIMEOUT,
 5291                cx.background_executor().clone(),
 5292                request.to_proto(project_id, buffer.read(cx)),
 5293            );
 5294            let buffer = buffer.clone();
 5295            cx.spawn(async move |weak_project, cx| {
 5296                let Some(project) = weak_project.upgrade() else {
 5297                    return Ok(None);
 5298                };
 5299                let Some(responses) = request_task.await? else {
 5300                    return Ok(None);
 5301                };
 5302                let actions = join_all(responses.payload.into_iter().map(|response| {
 5303                    GetDeclarations { position }.response_from_proto(
 5304                        response.response,
 5305                        project.clone(),
 5306                        buffer.clone(),
 5307                        cx.clone(),
 5308                    )
 5309                }))
 5310                .await;
 5311
 5312                Ok(Some(
 5313                    actions
 5314                        .into_iter()
 5315                        .collect::<Result<Vec<Vec<_>>>>()?
 5316                        .into_iter()
 5317                        .flatten()
 5318                        .dedup()
 5319                        .collect(),
 5320                ))
 5321            })
 5322        } else {
 5323            let declarations_task = self.request_multiple_lsp_locally(
 5324                buffer,
 5325                Some(position),
 5326                GetDeclarations { position },
 5327                cx,
 5328            );
 5329            cx.background_spawn(async move {
 5330                Ok(Some(
 5331                    declarations_task
 5332                        .await
 5333                        .into_iter()
 5334                        .flat_map(|(_, declarations)| declarations)
 5335                        .dedup()
 5336                        .collect(),
 5337                ))
 5338            })
 5339        }
 5340    }
 5341
 5342    pub fn type_definitions(
 5343        &mut self,
 5344        buffer: &Entity<Buffer>,
 5345        position: PointUtf16,
 5346        cx: &mut Context<Self>,
 5347    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5348        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5349            let request = GetTypeDefinitions { position };
 5350            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5351                return Task::ready(Ok(None));
 5352            }
 5353            let request_task = upstream_client.request_lsp(
 5354                project_id,
 5355                LSP_REQUEST_TIMEOUT,
 5356                cx.background_executor().clone(),
 5357                request.to_proto(project_id, buffer.read(cx)),
 5358            );
 5359            let buffer = buffer.clone();
 5360            cx.spawn(async move |weak_project, cx| {
 5361                let Some(project) = weak_project.upgrade() else {
 5362                    return Ok(None);
 5363                };
 5364                let Some(responses) = request_task.await? else {
 5365                    return Ok(None);
 5366                };
 5367                let actions = join_all(responses.payload.into_iter().map(|response| {
 5368                    GetTypeDefinitions { position }.response_from_proto(
 5369                        response.response,
 5370                        project.clone(),
 5371                        buffer.clone(),
 5372                        cx.clone(),
 5373                    )
 5374                }))
 5375                .await;
 5376
 5377                Ok(Some(
 5378                    actions
 5379                        .into_iter()
 5380                        .collect::<Result<Vec<Vec<_>>>>()?
 5381                        .into_iter()
 5382                        .flatten()
 5383                        .dedup()
 5384                        .collect(),
 5385                ))
 5386            })
 5387        } else {
 5388            let type_definitions_task = self.request_multiple_lsp_locally(
 5389                buffer,
 5390                Some(position),
 5391                GetTypeDefinitions { position },
 5392                cx,
 5393            );
 5394            cx.background_spawn(async move {
 5395                Ok(Some(
 5396                    type_definitions_task
 5397                        .await
 5398                        .into_iter()
 5399                        .flat_map(|(_, type_definitions)| type_definitions)
 5400                        .dedup()
 5401                        .collect(),
 5402                ))
 5403            })
 5404        }
 5405    }
 5406
 5407    pub fn implementations(
 5408        &mut self,
 5409        buffer: &Entity<Buffer>,
 5410        position: PointUtf16,
 5411        cx: &mut Context<Self>,
 5412    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5413        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5414            let request = GetImplementations { position };
 5415            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5416                return Task::ready(Ok(None));
 5417            }
 5418            let request_task = upstream_client.request_lsp(
 5419                project_id,
 5420                LSP_REQUEST_TIMEOUT,
 5421                cx.background_executor().clone(),
 5422                request.to_proto(project_id, buffer.read(cx)),
 5423            );
 5424            let buffer = buffer.clone();
 5425            cx.spawn(async move |weak_project, cx| {
 5426                let Some(project) = weak_project.upgrade() else {
 5427                    return Ok(None);
 5428                };
 5429                let Some(responses) = request_task.await? else {
 5430                    return Ok(None);
 5431                };
 5432                let actions = join_all(responses.payload.into_iter().map(|response| {
 5433                    GetImplementations { position }.response_from_proto(
 5434                        response.response,
 5435                        project.clone(),
 5436                        buffer.clone(),
 5437                        cx.clone(),
 5438                    )
 5439                }))
 5440                .await;
 5441
 5442                Ok(Some(
 5443                    actions
 5444                        .into_iter()
 5445                        .collect::<Result<Vec<Vec<_>>>>()?
 5446                        .into_iter()
 5447                        .flatten()
 5448                        .dedup()
 5449                        .collect(),
 5450                ))
 5451            })
 5452        } else {
 5453            let implementations_task = self.request_multiple_lsp_locally(
 5454                buffer,
 5455                Some(position),
 5456                GetImplementations { position },
 5457                cx,
 5458            );
 5459            cx.background_spawn(async move {
 5460                Ok(Some(
 5461                    implementations_task
 5462                        .await
 5463                        .into_iter()
 5464                        .flat_map(|(_, implementations)| implementations)
 5465                        .dedup()
 5466                        .collect(),
 5467                ))
 5468            })
 5469        }
 5470    }
 5471
 5472    pub fn references(
 5473        &mut self,
 5474        buffer: &Entity<Buffer>,
 5475        position: PointUtf16,
 5476        cx: &mut Context<Self>,
 5477    ) -> Task<Result<Option<Vec<Location>>>> {
 5478        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5479            let request = GetReferences { position };
 5480            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5481                return Task::ready(Ok(None));
 5482            }
 5483
 5484            let request_task = upstream_client.request_lsp(
 5485                project_id,
 5486                LSP_REQUEST_TIMEOUT,
 5487                cx.background_executor().clone(),
 5488                request.to_proto(project_id, buffer.read(cx)),
 5489            );
 5490            let buffer = buffer.clone();
 5491            cx.spawn(async move |weak_project, cx| {
 5492                let Some(project) = weak_project.upgrade() else {
 5493                    return Ok(None);
 5494                };
 5495                let Some(responses) = request_task.await? else {
 5496                    return Ok(None);
 5497                };
 5498
 5499                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5500                    GetReferences { position }.response_from_proto(
 5501                        lsp_response.response,
 5502                        project.clone(),
 5503                        buffer.clone(),
 5504                        cx.clone(),
 5505                    )
 5506                }))
 5507                .await
 5508                .into_iter()
 5509                .collect::<Result<Vec<Vec<_>>>>()?
 5510                .into_iter()
 5511                .flatten()
 5512                .dedup()
 5513                .collect();
 5514                Ok(Some(locations))
 5515            })
 5516        } else {
 5517            let references_task = self.request_multiple_lsp_locally(
 5518                buffer,
 5519                Some(position),
 5520                GetReferences { position },
 5521                cx,
 5522            );
 5523            cx.background_spawn(async move {
 5524                Ok(Some(
 5525                    references_task
 5526                        .await
 5527                        .into_iter()
 5528                        .flat_map(|(_, references)| references)
 5529                        .dedup()
 5530                        .collect(),
 5531                ))
 5532            })
 5533        }
 5534    }
 5535
 5536    pub fn code_actions(
 5537        &mut self,
 5538        buffer: &Entity<Buffer>,
 5539        range: Range<Anchor>,
 5540        kinds: Option<Vec<CodeActionKind>>,
 5541        cx: &mut Context<Self>,
 5542    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5543        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5544            let request = GetCodeActions {
 5545                range: range.clone(),
 5546                kinds: kinds.clone(),
 5547            };
 5548            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5549                return Task::ready(Ok(None));
 5550            }
 5551            let request_task = upstream_client.request_lsp(
 5552                project_id,
 5553                LSP_REQUEST_TIMEOUT,
 5554                cx.background_executor().clone(),
 5555                request.to_proto(project_id, buffer.read(cx)),
 5556            );
 5557            let buffer = buffer.clone();
 5558            cx.spawn(async move |weak_project, cx| {
 5559                let Some(project) = weak_project.upgrade() else {
 5560                    return Ok(None);
 5561                };
 5562                let Some(responses) = request_task.await? else {
 5563                    return Ok(None);
 5564                };
 5565                let actions = join_all(responses.payload.into_iter().map(|response| {
 5566                    GetCodeActions {
 5567                        range: range.clone(),
 5568                        kinds: kinds.clone(),
 5569                    }
 5570                    .response_from_proto(
 5571                        response.response,
 5572                        project.clone(),
 5573                        buffer.clone(),
 5574                        cx.clone(),
 5575                    )
 5576                }))
 5577                .await;
 5578
 5579                Ok(Some(
 5580                    actions
 5581                        .into_iter()
 5582                        .collect::<Result<Vec<Vec<_>>>>()?
 5583                        .into_iter()
 5584                        .flatten()
 5585                        .collect(),
 5586                ))
 5587            })
 5588        } else {
 5589            let all_actions_task = self.request_multiple_lsp_locally(
 5590                buffer,
 5591                Some(range.start),
 5592                GetCodeActions { range, kinds },
 5593                cx,
 5594            );
 5595            cx.background_spawn(async move {
 5596                Ok(Some(
 5597                    all_actions_task
 5598                        .await
 5599                        .into_iter()
 5600                        .flat_map(|(_, actions)| actions)
 5601                        .collect(),
 5602                ))
 5603            })
 5604        }
 5605    }
 5606
 5607    pub fn code_lens_actions(
 5608        &mut self,
 5609        buffer: &Entity<Buffer>,
 5610        cx: &mut Context<Self>,
 5611    ) -> CodeLensTask {
 5612        let version_queried_for = buffer.read(cx).version();
 5613        let buffer_id = buffer.read(cx).remote_id();
 5614
 5615        if let Some(cached_data) = self.lsp_code_lens.get(&buffer_id)
 5616            && !version_queried_for.changed_since(&cached_data.lens_for_version)
 5617        {
 5618            let has_different_servers = self.as_local().is_some_and(|local| {
 5619                local
 5620                    .buffers_opened_in_servers
 5621                    .get(&buffer_id)
 5622                    .cloned()
 5623                    .unwrap_or_default()
 5624                    != cached_data.lens.keys().copied().collect()
 5625            });
 5626            if !has_different_servers {
 5627                return Task::ready(Ok(Some(
 5628                    cached_data.lens.values().flatten().cloned().collect(),
 5629                )))
 5630                .shared();
 5631            }
 5632        }
 5633
 5634        let lsp_data = self.lsp_code_lens.entry(buffer_id).or_default();
 5635        if let Some((updating_for, running_update)) = &lsp_data.update
 5636            && !version_queried_for.changed_since(updating_for)
 5637        {
 5638            return running_update.clone();
 5639        }
 5640        let buffer = buffer.clone();
 5641        let query_version_queried_for = version_queried_for.clone();
 5642        let new_task = cx
 5643            .spawn(async move |lsp_store, cx| {
 5644                cx.background_executor()
 5645                    .timer(Duration::from_millis(30))
 5646                    .await;
 5647                let fetched_lens = lsp_store
 5648                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5649                    .map_err(Arc::new)?
 5650                    .await
 5651                    .context("fetching code lens")
 5652                    .map_err(Arc::new);
 5653                let fetched_lens = match fetched_lens {
 5654                    Ok(fetched_lens) => fetched_lens,
 5655                    Err(e) => {
 5656                        lsp_store
 5657                            .update(cx, |lsp_store, _| {
 5658                                lsp_store.lsp_code_lens.entry(buffer_id).or_default().update = None;
 5659                            })
 5660                            .ok();
 5661                        return Err(e);
 5662                    }
 5663                };
 5664
 5665                lsp_store
 5666                    .update(cx, |lsp_store, _| {
 5667                        let lsp_data = lsp_store.lsp_code_lens.entry(buffer_id).or_default();
 5668                        if let Some(fetched_lens) = fetched_lens {
 5669                            if lsp_data.lens_for_version == query_version_queried_for {
 5670                                lsp_data.lens.extend(fetched_lens);
 5671                            } else if !lsp_data
 5672                                .lens_for_version
 5673                                .changed_since(&query_version_queried_for)
 5674                            {
 5675                                lsp_data.lens_for_version = query_version_queried_for;
 5676                                lsp_data.lens = fetched_lens;
 5677                            }
 5678                        }
 5679                        lsp_data.update = None;
 5680                        Some(lsp_data.lens.values().flatten().cloned().collect())
 5681                    })
 5682                    .map_err(Arc::new)
 5683            })
 5684            .shared();
 5685        lsp_data.update = Some((version_queried_for, new_task.clone()));
 5686        new_task
 5687    }
 5688
 5689    fn fetch_code_lens(
 5690        &mut self,
 5691        buffer: &Entity<Buffer>,
 5692        cx: &mut Context<Self>,
 5693    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5694        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5695            let request = GetCodeLens;
 5696            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5697                return Task::ready(Ok(None));
 5698            }
 5699            let request_task = upstream_client.request_lsp(
 5700                project_id,
 5701                LSP_REQUEST_TIMEOUT,
 5702                cx.background_executor().clone(),
 5703                request.to_proto(project_id, buffer.read(cx)),
 5704            );
 5705            let buffer = buffer.clone();
 5706            cx.spawn(async move |weak_lsp_store, cx| {
 5707                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5708                    return Ok(None);
 5709                };
 5710                let Some(responses) = request_task.await? else {
 5711                    return Ok(None);
 5712                };
 5713
 5714                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5715                    let lsp_store = lsp_store.clone();
 5716                    let buffer = buffer.clone();
 5717                    let cx = cx.clone();
 5718                    async move {
 5719                        (
 5720                            LanguageServerId::from_proto(response.server_id),
 5721                            GetCodeLens
 5722                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5723                                .await,
 5724                        )
 5725                    }
 5726                }))
 5727                .await;
 5728
 5729                let mut has_errors = false;
 5730                let code_lens_actions = code_lens_actions
 5731                    .into_iter()
 5732                    .filter_map(|(server_id, code_lens)| match code_lens {
 5733                        Ok(code_lens) => Some((server_id, code_lens)),
 5734                        Err(e) => {
 5735                            has_errors = true;
 5736                            log::error!("{e:#}");
 5737                            None
 5738                        }
 5739                    })
 5740                    .collect::<HashMap<_, _>>();
 5741                anyhow::ensure!(
 5742                    !has_errors || !code_lens_actions.is_empty(),
 5743                    "Failed to fetch code lens"
 5744                );
 5745                Ok(Some(code_lens_actions))
 5746            })
 5747        } else {
 5748            let code_lens_actions_task =
 5749                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5750            cx.background_spawn(async move {
 5751                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5752            })
 5753        }
 5754    }
 5755
 5756    #[inline(never)]
 5757    pub fn completions(
 5758        &self,
 5759        buffer: &Entity<Buffer>,
 5760        position: PointUtf16,
 5761        context: CompletionContext,
 5762        cx: &mut Context<Self>,
 5763    ) -> Task<Result<Vec<CompletionResponse>>> {
 5764        let language_registry = self.languages.clone();
 5765
 5766        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5767            let request = GetCompletions { position, context };
 5768            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5769                return Task::ready(Ok(Vec::new()));
 5770            }
 5771            let task = self.send_lsp_proto_request(
 5772                buffer.clone(),
 5773                upstream_client,
 5774                project_id,
 5775                request,
 5776                cx,
 5777            );
 5778            let language = buffer.read(cx).language().cloned();
 5779
 5780            // In the future, we should provide project guests with the names of LSP adapters,
 5781            // so that they can use the correct LSP adapter when computing labels. For now,
 5782            // guests just use the first LSP adapter associated with the buffer's language.
 5783            let lsp_adapter = language.as_ref().and_then(|language| {
 5784                language_registry
 5785                    .lsp_adapters(&language.name())
 5786                    .first()
 5787                    .cloned()
 5788            });
 5789
 5790            cx.foreground_executor().spawn(async move {
 5791                let completion_response = task.await?;
 5792                let completions = populate_labels_for_completions(
 5793                    completion_response.completions,
 5794                    language,
 5795                    lsp_adapter,
 5796                )
 5797                .await;
 5798                Ok(vec![CompletionResponse {
 5799                    completions,
 5800                    display_options: CompletionDisplayOptions::default(),
 5801                    is_incomplete: completion_response.is_incomplete,
 5802                }])
 5803            })
 5804        } else if let Some(local) = self.as_local() {
 5805            let snapshot = buffer.read(cx).snapshot();
 5806            let offset = position.to_offset(&snapshot);
 5807            let scope = snapshot.language_scope_at(offset);
 5808            let language = snapshot.language().cloned();
 5809            let completion_settings = language_settings(
 5810                language.as_ref().map(|language| language.name()),
 5811                buffer.read(cx).file(),
 5812                cx,
 5813            )
 5814            .completions;
 5815            if !completion_settings.lsp {
 5816                return Task::ready(Ok(Vec::new()));
 5817            }
 5818
 5819            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5820                local
 5821                    .language_servers_for_buffer(buffer, cx)
 5822                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5823                    .filter(|(adapter, _)| {
 5824                        scope
 5825                            .as_ref()
 5826                            .map(|scope| scope.language_allowed(&adapter.name))
 5827                            .unwrap_or(true)
 5828                    })
 5829                    .map(|(_, server)| server.server_id())
 5830                    .collect()
 5831            });
 5832
 5833            let buffer = buffer.clone();
 5834            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5835            let lsp_timeout = if lsp_timeout > 0 {
 5836                Some(Duration::from_millis(lsp_timeout))
 5837            } else {
 5838                None
 5839            };
 5840            cx.spawn(async move |this,  cx| {
 5841                let mut tasks = Vec::with_capacity(server_ids.len());
 5842                this.update(cx, |lsp_store, cx| {
 5843                    for server_id in server_ids {
 5844                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5845                        let lsp_timeout = lsp_timeout
 5846                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5847                        let mut timeout = cx.background_spawn(async move {
 5848                            match lsp_timeout {
 5849                                Some(lsp_timeout) => {
 5850                                    lsp_timeout.await;
 5851                                    true
 5852                                },
 5853                                None => false,
 5854                            }
 5855                        }).fuse();
 5856                        let mut lsp_request = lsp_store.request_lsp(
 5857                            buffer.clone(),
 5858                            LanguageServerToQuery::Other(server_id),
 5859                            GetCompletions {
 5860                                position,
 5861                                context: context.clone(),
 5862                            },
 5863                            cx,
 5864                        ).fuse();
 5865                        let new_task = cx.background_spawn(async move {
 5866                            select_biased! {
 5867                                response = lsp_request => anyhow::Ok(Some(response?)),
 5868                                timeout_happened = timeout => {
 5869                                    if timeout_happened {
 5870                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5871                                        Ok(None)
 5872                                    } else {
 5873                                        let completions = lsp_request.await?;
 5874                                        Ok(Some(completions))
 5875                                    }
 5876                                },
 5877                            }
 5878                        });
 5879                        tasks.push((lsp_adapter, new_task));
 5880                    }
 5881                })?;
 5882
 5883                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5884                    let completion_response = task.await.ok()??;
 5885                    let completions = populate_labels_for_completions(
 5886                            completion_response.completions,
 5887                            language.clone(),
 5888                            lsp_adapter,
 5889                        )
 5890                        .await;
 5891                    Some(CompletionResponse {
 5892                        completions,
 5893                        display_options: CompletionDisplayOptions::default(),
 5894                        is_incomplete: completion_response.is_incomplete,
 5895                    })
 5896                });
 5897
 5898                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5899
 5900                Ok(responses.into_iter().flatten().collect())
 5901            })
 5902        } else {
 5903            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5904        }
 5905    }
 5906
 5907    pub fn resolve_completions(
 5908        &self,
 5909        buffer: Entity<Buffer>,
 5910        completion_indices: Vec<usize>,
 5911        completions: Rc<RefCell<Box<[Completion]>>>,
 5912        cx: &mut Context<Self>,
 5913    ) -> Task<Result<bool>> {
 5914        let client = self.upstream_client();
 5915        let buffer_id = buffer.read(cx).remote_id();
 5916        let buffer_snapshot = buffer.read(cx).snapshot();
 5917
 5918        if !self.check_if_capable_for_proto_request(
 5919            &buffer,
 5920            GetCompletions::can_resolve_completions,
 5921            cx,
 5922        ) {
 5923            return Task::ready(Ok(false));
 5924        }
 5925        cx.spawn(async move |lsp_store, cx| {
 5926            let mut did_resolve = false;
 5927            if let Some((client, project_id)) = client {
 5928                for completion_index in completion_indices {
 5929                    let server_id = {
 5930                        let completion = &completions.borrow()[completion_index];
 5931                        completion.source.server_id()
 5932                    };
 5933                    if let Some(server_id) = server_id {
 5934                        if Self::resolve_completion_remote(
 5935                            project_id,
 5936                            server_id,
 5937                            buffer_id,
 5938                            completions.clone(),
 5939                            completion_index,
 5940                            client.clone(),
 5941                        )
 5942                        .await
 5943                        .log_err()
 5944                        .is_some()
 5945                        {
 5946                            did_resolve = true;
 5947                        }
 5948                    } else {
 5949                        resolve_word_completion(
 5950                            &buffer_snapshot,
 5951                            &mut completions.borrow_mut()[completion_index],
 5952                        );
 5953                    }
 5954                }
 5955            } else {
 5956                for completion_index in completion_indices {
 5957                    let server_id = {
 5958                        let completion = &completions.borrow()[completion_index];
 5959                        completion.source.server_id()
 5960                    };
 5961                    if let Some(server_id) = server_id {
 5962                        let server_and_adapter = lsp_store
 5963                            .read_with(cx, |lsp_store, _| {
 5964                                let server = lsp_store.language_server_for_id(server_id)?;
 5965                                let adapter =
 5966                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5967                                Some((server, adapter))
 5968                            })
 5969                            .ok()
 5970                            .flatten();
 5971                        let Some((server, adapter)) = server_and_adapter else {
 5972                            continue;
 5973                        };
 5974
 5975                        let resolved = Self::resolve_completion_local(
 5976                            server,
 5977                            completions.clone(),
 5978                            completion_index,
 5979                        )
 5980                        .await
 5981                        .log_err()
 5982                        .is_some();
 5983                        if resolved {
 5984                            Self::regenerate_completion_labels(
 5985                                adapter,
 5986                                &buffer_snapshot,
 5987                                completions.clone(),
 5988                                completion_index,
 5989                            )
 5990                            .await
 5991                            .log_err();
 5992                            did_resolve = true;
 5993                        }
 5994                    } else {
 5995                        resolve_word_completion(
 5996                            &buffer_snapshot,
 5997                            &mut completions.borrow_mut()[completion_index],
 5998                        );
 5999                    }
 6000                }
 6001            }
 6002
 6003            Ok(did_resolve)
 6004        })
 6005    }
 6006
 6007    async fn resolve_completion_local(
 6008        server: Arc<lsp::LanguageServer>,
 6009        completions: Rc<RefCell<Box<[Completion]>>>,
 6010        completion_index: usize,
 6011    ) -> Result<()> {
 6012        let server_id = server.server_id();
 6013        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6014            return Ok(());
 6015        }
 6016
 6017        let request = {
 6018            let completion = &completions.borrow()[completion_index];
 6019            match &completion.source {
 6020                CompletionSource::Lsp {
 6021                    lsp_completion,
 6022                    resolved,
 6023                    server_id: completion_server_id,
 6024                    ..
 6025                } => {
 6026                    if *resolved {
 6027                        return Ok(());
 6028                    }
 6029                    anyhow::ensure!(
 6030                        server_id == *completion_server_id,
 6031                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6032                    );
 6033                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6034                }
 6035                CompletionSource::BufferWord { .. }
 6036                | CompletionSource::Dap { .. }
 6037                | CompletionSource::Custom => {
 6038                    return Ok(());
 6039                }
 6040            }
 6041        };
 6042        let resolved_completion = request
 6043            .await
 6044            .into_response()
 6045            .context("resolve completion")?;
 6046
 6047        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6048        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6049
 6050        let mut completions = completions.borrow_mut();
 6051        let completion = &mut completions[completion_index];
 6052        if let CompletionSource::Lsp {
 6053            lsp_completion,
 6054            resolved,
 6055            server_id: completion_server_id,
 6056            ..
 6057        } = &mut completion.source
 6058        {
 6059            if *resolved {
 6060                return Ok(());
 6061            }
 6062            anyhow::ensure!(
 6063                server_id == *completion_server_id,
 6064                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6065            );
 6066            *lsp_completion = Box::new(resolved_completion);
 6067            *resolved = true;
 6068        }
 6069        Ok(())
 6070    }
 6071
 6072    async fn regenerate_completion_labels(
 6073        adapter: Arc<CachedLspAdapter>,
 6074        snapshot: &BufferSnapshot,
 6075        completions: Rc<RefCell<Box<[Completion]>>>,
 6076        completion_index: usize,
 6077    ) -> Result<()> {
 6078        let completion_item = completions.borrow()[completion_index]
 6079            .source
 6080            .lsp_completion(true)
 6081            .map(Cow::into_owned);
 6082        if let Some(lsp_documentation) = completion_item
 6083            .as_ref()
 6084            .and_then(|completion_item| completion_item.documentation.clone())
 6085        {
 6086            let mut completions = completions.borrow_mut();
 6087            let completion = &mut completions[completion_index];
 6088            completion.documentation = Some(lsp_documentation.into());
 6089        } else {
 6090            let mut completions = completions.borrow_mut();
 6091            let completion = &mut completions[completion_index];
 6092            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6093        }
 6094
 6095        let mut new_label = match completion_item {
 6096            Some(completion_item) => {
 6097                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6098                // So we have to update the label here anyway...
 6099                let language = snapshot.language();
 6100                match language {
 6101                    Some(language) => {
 6102                        adapter
 6103                            .labels_for_completions(
 6104                                std::slice::from_ref(&completion_item),
 6105                                language,
 6106                            )
 6107                            .await?
 6108                    }
 6109                    None => Vec::new(),
 6110                }
 6111                .pop()
 6112                .flatten()
 6113                .unwrap_or_else(|| {
 6114                    CodeLabel::fallback_for_completion(
 6115                        &completion_item,
 6116                        language.map(|language| language.as_ref()),
 6117                    )
 6118                })
 6119            }
 6120            None => CodeLabel::plain(
 6121                completions.borrow()[completion_index].new_text.clone(),
 6122                None,
 6123            ),
 6124        };
 6125        ensure_uniform_list_compatible_label(&mut new_label);
 6126
 6127        let mut completions = completions.borrow_mut();
 6128        let completion = &mut completions[completion_index];
 6129        if completion.label.filter_text() == new_label.filter_text() {
 6130            completion.label = new_label;
 6131        } else {
 6132            log::error!(
 6133                "Resolved completion changed display label from {} to {}. \
 6134                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6135                completion.label.text(),
 6136                new_label.text(),
 6137                completion.label.filter_text(),
 6138                new_label.filter_text()
 6139            );
 6140        }
 6141
 6142        Ok(())
 6143    }
 6144
 6145    async fn resolve_completion_remote(
 6146        project_id: u64,
 6147        server_id: LanguageServerId,
 6148        buffer_id: BufferId,
 6149        completions: Rc<RefCell<Box<[Completion]>>>,
 6150        completion_index: usize,
 6151        client: AnyProtoClient,
 6152    ) -> Result<()> {
 6153        let lsp_completion = {
 6154            let completion = &completions.borrow()[completion_index];
 6155            match &completion.source {
 6156                CompletionSource::Lsp {
 6157                    lsp_completion,
 6158                    resolved,
 6159                    server_id: completion_server_id,
 6160                    ..
 6161                } => {
 6162                    anyhow::ensure!(
 6163                        server_id == *completion_server_id,
 6164                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6165                    );
 6166                    if *resolved {
 6167                        return Ok(());
 6168                    }
 6169                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6170                }
 6171                CompletionSource::Custom
 6172                | CompletionSource::Dap { .. }
 6173                | CompletionSource::BufferWord { .. } => {
 6174                    return Ok(());
 6175                }
 6176            }
 6177        };
 6178        let request = proto::ResolveCompletionDocumentation {
 6179            project_id,
 6180            language_server_id: server_id.0 as u64,
 6181            lsp_completion,
 6182            buffer_id: buffer_id.into(),
 6183        };
 6184
 6185        let response = client
 6186            .request(request)
 6187            .await
 6188            .context("completion documentation resolve proto request")?;
 6189        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6190
 6191        let documentation = if response.documentation.is_empty() {
 6192            CompletionDocumentation::Undocumented
 6193        } else if response.documentation_is_markdown {
 6194            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6195        } else if response.documentation.lines().count() <= 1 {
 6196            CompletionDocumentation::SingleLine(response.documentation.into())
 6197        } else {
 6198            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6199        };
 6200
 6201        let mut completions = completions.borrow_mut();
 6202        let completion = &mut completions[completion_index];
 6203        completion.documentation = Some(documentation);
 6204        if let CompletionSource::Lsp {
 6205            insert_range,
 6206            lsp_completion,
 6207            resolved,
 6208            server_id: completion_server_id,
 6209            lsp_defaults: _,
 6210        } = &mut completion.source
 6211        {
 6212            let completion_insert_range = response
 6213                .old_insert_start
 6214                .and_then(deserialize_anchor)
 6215                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6216            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6217
 6218            if *resolved {
 6219                return Ok(());
 6220            }
 6221            anyhow::ensure!(
 6222                server_id == *completion_server_id,
 6223                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6224            );
 6225            *lsp_completion = Box::new(resolved_lsp_completion);
 6226            *resolved = true;
 6227        }
 6228
 6229        let replace_range = response
 6230            .old_replace_start
 6231            .and_then(deserialize_anchor)
 6232            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6233        if let Some((old_replace_start, old_replace_end)) = replace_range
 6234            && !response.new_text.is_empty()
 6235        {
 6236            completion.new_text = response.new_text;
 6237            completion.replace_range = old_replace_start..old_replace_end;
 6238        }
 6239
 6240        Ok(())
 6241    }
 6242
 6243    pub fn apply_additional_edits_for_completion(
 6244        &self,
 6245        buffer_handle: Entity<Buffer>,
 6246        completions: Rc<RefCell<Box<[Completion]>>>,
 6247        completion_index: usize,
 6248        push_to_history: bool,
 6249        cx: &mut Context<Self>,
 6250    ) -> Task<Result<Option<Transaction>>> {
 6251        if let Some((client, project_id)) = self.upstream_client() {
 6252            let buffer = buffer_handle.read(cx);
 6253            let buffer_id = buffer.remote_id();
 6254            cx.spawn(async move |_, cx| {
 6255                let request = {
 6256                    let completion = completions.borrow()[completion_index].clone();
 6257                    proto::ApplyCompletionAdditionalEdits {
 6258                        project_id,
 6259                        buffer_id: buffer_id.into(),
 6260                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6261                            replace_range: completion.replace_range,
 6262                            new_text: completion.new_text,
 6263                            source: completion.source,
 6264                        })),
 6265                    }
 6266                };
 6267
 6268                if let Some(transaction) = client.request(request).await?.transaction {
 6269                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6270                    buffer_handle
 6271                        .update(cx, |buffer, _| {
 6272                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6273                        })?
 6274                        .await?;
 6275                    if push_to_history {
 6276                        buffer_handle.update(cx, |buffer, _| {
 6277                            buffer.push_transaction(transaction.clone(), Instant::now());
 6278                            buffer.finalize_last_transaction();
 6279                        })?;
 6280                    }
 6281                    Ok(Some(transaction))
 6282                } else {
 6283                    Ok(None)
 6284                }
 6285            })
 6286        } else {
 6287            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6288                let completion = &completions.borrow()[completion_index];
 6289                let server_id = completion.source.server_id()?;
 6290                Some(
 6291                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6292                        .1
 6293                        .clone(),
 6294                )
 6295            }) else {
 6296                return Task::ready(Ok(None));
 6297            };
 6298
 6299            cx.spawn(async move |this, cx| {
 6300                Self::resolve_completion_local(
 6301                    server.clone(),
 6302                    completions.clone(),
 6303                    completion_index,
 6304                )
 6305                .await
 6306                .context("resolving completion")?;
 6307                let completion = completions.borrow()[completion_index].clone();
 6308                let additional_text_edits = completion
 6309                    .source
 6310                    .lsp_completion(true)
 6311                    .as_ref()
 6312                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6313                if let Some(edits) = additional_text_edits {
 6314                    let edits = this
 6315                        .update(cx, |this, cx| {
 6316                            this.as_local_mut().unwrap().edits_from_lsp(
 6317                                &buffer_handle,
 6318                                edits,
 6319                                server.server_id(),
 6320                                None,
 6321                                cx,
 6322                            )
 6323                        })?
 6324                        .await?;
 6325
 6326                    buffer_handle.update(cx, |buffer, cx| {
 6327                        buffer.finalize_last_transaction();
 6328                        buffer.start_transaction();
 6329
 6330                        for (range, text) in edits {
 6331                            let primary = &completion.replace_range;
 6332
 6333                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6334                            // and the primary completion is just an insertion (empty range), then this is likely
 6335                            // an auto-import scenario and should not be considered overlapping
 6336                            // https://github.com/zed-industries/zed/issues/26136
 6337                            let is_file_start_auto_import = {
 6338                                let snapshot = buffer.snapshot();
 6339                                let primary_start_point = primary.start.to_point(&snapshot);
 6340                                let range_start_point = range.start.to_point(&snapshot);
 6341
 6342                                let result = primary_start_point.row == 0
 6343                                    && primary_start_point.column == 0
 6344                                    && range_start_point.row == 0
 6345                                    && range_start_point.column == 0;
 6346
 6347                                result
 6348                            };
 6349
 6350                            let has_overlap = if is_file_start_auto_import {
 6351                                false
 6352                            } else {
 6353                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6354                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6355                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6356                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6357                                let result = start_within || end_within;
 6358                                result
 6359                            };
 6360
 6361                            //Skip additional edits which overlap with the primary completion edit
 6362                            //https://github.com/zed-industries/zed/pull/1871
 6363                            if !has_overlap {
 6364                                buffer.edit([(range, text)], None, cx);
 6365                            }
 6366                        }
 6367
 6368                        let transaction = if buffer.end_transaction(cx).is_some() {
 6369                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6370                            if !push_to_history {
 6371                                buffer.forget_transaction(transaction.id);
 6372                            }
 6373                            Some(transaction)
 6374                        } else {
 6375                            None
 6376                        };
 6377                        Ok(transaction)
 6378                    })?
 6379                } else {
 6380                    Ok(None)
 6381                }
 6382            })
 6383        }
 6384    }
 6385
 6386    pub fn pull_diagnostics(
 6387        &mut self,
 6388        buffer: Entity<Buffer>,
 6389        cx: &mut Context<Self>,
 6390    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6391        let buffer_id = buffer.read(cx).remote_id();
 6392
 6393        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6394            let request = GetDocumentDiagnostics {
 6395                previous_result_id: None,
 6396            };
 6397            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6398                return Task::ready(Ok(None));
 6399            }
 6400            let request_task = client.request_lsp(
 6401                upstream_project_id,
 6402                LSP_REQUEST_TIMEOUT,
 6403                cx.background_executor().clone(),
 6404                request.to_proto(upstream_project_id, buffer.read(cx)),
 6405            );
 6406            cx.background_spawn(async move {
 6407                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6408                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6409                // Do not attempt to further process the dummy responses here.
 6410                let _response = request_task.await?;
 6411                Ok(None)
 6412            })
 6413        } else {
 6414            let server_ids = buffer.update(cx, |buffer, cx| {
 6415                self.language_servers_for_local_buffer(buffer, cx)
 6416                    .map(|(_, server)| server.server_id())
 6417                    .collect::<Vec<_>>()
 6418            });
 6419            let pull_diagnostics = server_ids
 6420                .into_iter()
 6421                .map(|server_id| {
 6422                    let result_id = self.result_id(server_id, buffer_id, cx);
 6423                    self.request_lsp(
 6424                        buffer.clone(),
 6425                        LanguageServerToQuery::Other(server_id),
 6426                        GetDocumentDiagnostics {
 6427                            previous_result_id: result_id,
 6428                        },
 6429                        cx,
 6430                    )
 6431                })
 6432                .collect::<Vec<_>>();
 6433
 6434            cx.background_spawn(async move {
 6435                let mut responses = Vec::new();
 6436                for diagnostics in join_all(pull_diagnostics).await {
 6437                    responses.extend(diagnostics?);
 6438                }
 6439                Ok(Some(responses))
 6440            })
 6441        }
 6442    }
 6443
 6444    pub fn inlay_hints(
 6445        &mut self,
 6446        buffer: Entity<Buffer>,
 6447        range: Range<Anchor>,
 6448        cx: &mut Context<Self>,
 6449    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6450        let range_start = range.start;
 6451        let range_end = range.end;
 6452        let buffer_id = buffer.read(cx).remote_id().into();
 6453        let request = InlayHints { range };
 6454
 6455        if let Some((client, project_id)) = self.upstream_client() {
 6456            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6457                return Task::ready(Ok(Vec::new()));
 6458            }
 6459            let proto_request = proto::InlayHints {
 6460                project_id,
 6461                buffer_id,
 6462                start: Some(serialize_anchor(&range_start)),
 6463                end: Some(serialize_anchor(&range_end)),
 6464                version: serialize_version(&buffer.read(cx).version()),
 6465            };
 6466            cx.spawn(async move |project, cx| {
 6467                let response = client
 6468                    .request(proto_request)
 6469                    .await
 6470                    .context("inlay hints proto request")?;
 6471                LspCommand::response_from_proto(
 6472                    request,
 6473                    response,
 6474                    project.upgrade().context("No project")?,
 6475                    buffer.clone(),
 6476                    cx.clone(),
 6477                )
 6478                .await
 6479                .context("inlay hints proto response conversion")
 6480            })
 6481        } else {
 6482            let lsp_request_task = self.request_lsp(
 6483                buffer.clone(),
 6484                LanguageServerToQuery::FirstCapable,
 6485                request,
 6486                cx,
 6487            );
 6488            cx.spawn(async move |_, cx| {
 6489                buffer
 6490                    .update(cx, |buffer, _| {
 6491                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6492                    })?
 6493                    .await
 6494                    .context("waiting for inlay hint request range edits")?;
 6495                lsp_request_task.await.context("inlay hints LSP request")
 6496            })
 6497        }
 6498    }
 6499
 6500    pub fn pull_diagnostics_for_buffer(
 6501        &mut self,
 6502        buffer: Entity<Buffer>,
 6503        cx: &mut Context<Self>,
 6504    ) -> Task<anyhow::Result<()>> {
 6505        let diagnostics = self.pull_diagnostics(buffer, cx);
 6506        cx.spawn(async move |lsp_store, cx| {
 6507            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6508                return Ok(());
 6509            };
 6510            lsp_store.update(cx, |lsp_store, cx| {
 6511                if lsp_store.as_local().is_none() {
 6512                    return;
 6513                }
 6514
 6515                let mut unchanged_buffers = HashSet::default();
 6516                let mut changed_buffers = HashSet::default();
 6517                let server_diagnostics_updates = diagnostics
 6518                    .into_iter()
 6519                    .filter_map(|diagnostics_set| match diagnostics_set {
 6520                        LspPullDiagnostics::Response {
 6521                            server_id,
 6522                            uri,
 6523                            diagnostics,
 6524                        } => Some((server_id, uri, diagnostics)),
 6525                        LspPullDiagnostics::Default => None,
 6526                    })
 6527                    .fold(
 6528                        HashMap::default(),
 6529                        |mut acc, (server_id, uri, diagnostics)| {
 6530                            let (result_id, diagnostics) = match diagnostics {
 6531                                PulledDiagnostics::Unchanged { result_id } => {
 6532                                    unchanged_buffers.insert(uri.clone());
 6533                                    (Some(result_id), Vec::new())
 6534                                }
 6535                                PulledDiagnostics::Changed {
 6536                                    result_id,
 6537                                    diagnostics,
 6538                                } => {
 6539                                    changed_buffers.insert(uri.clone());
 6540                                    (result_id, diagnostics)
 6541                                }
 6542                            };
 6543                            let disk_based_sources = Cow::Owned(
 6544                                lsp_store
 6545                                    .language_server_adapter_for_id(server_id)
 6546                                    .as_ref()
 6547                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6548                                    .unwrap_or(&[])
 6549                                    .to_vec(),
 6550                            );
 6551                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6552                                DocumentDiagnosticsUpdate {
 6553                                    server_id,
 6554                                    diagnostics: lsp::PublishDiagnosticsParams {
 6555                                        uri,
 6556                                        diagnostics,
 6557                                        version: None,
 6558                                    },
 6559                                    result_id,
 6560                                    disk_based_sources,
 6561                                },
 6562                            );
 6563                            acc
 6564                        },
 6565                    );
 6566
 6567                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6568                    lsp_store
 6569                        .merge_lsp_diagnostics(
 6570                            DiagnosticSourceKind::Pulled,
 6571                            diagnostic_updates,
 6572                            |buffer, old_diagnostic, cx| {
 6573                                File::from_dyn(buffer.file())
 6574                                    .and_then(|file| {
 6575                                        let abs_path = file.as_local()?.abs_path(cx);
 6576                                        lsp::Uri::from_file_path(abs_path).ok()
 6577                                    })
 6578                                    .is_none_or(|buffer_uri| {
 6579                                        unchanged_buffers.contains(&buffer_uri)
 6580                                            || match old_diagnostic.source_kind {
 6581                                                DiagnosticSourceKind::Pulled => {
 6582                                                    !changed_buffers.contains(&buffer_uri)
 6583                                                }
 6584                                                DiagnosticSourceKind::Other
 6585                                                | DiagnosticSourceKind::Pushed => true,
 6586                                            }
 6587                                    })
 6588                            },
 6589                            cx,
 6590                        )
 6591                        .log_err();
 6592                }
 6593            })
 6594        })
 6595    }
 6596
 6597    pub fn document_colors(
 6598        &mut self,
 6599        fetch_strategy: LspFetchStrategy,
 6600        buffer: Entity<Buffer>,
 6601        cx: &mut Context<Self>,
 6602    ) -> Option<DocumentColorTask> {
 6603        let version_queried_for = buffer.read(cx).version();
 6604        let buffer_id = buffer.read(cx).remote_id();
 6605
 6606        match fetch_strategy {
 6607            LspFetchStrategy::IgnoreCache => {}
 6608            LspFetchStrategy::UseCache {
 6609                known_cache_version,
 6610            } => {
 6611                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6612                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6613                {
 6614                    let has_different_servers = self.as_local().is_some_and(|local| {
 6615                        local
 6616                            .buffers_opened_in_servers
 6617                            .get(&buffer_id)
 6618                            .cloned()
 6619                            .unwrap_or_default()
 6620                            != cached_data.colors.keys().copied().collect()
 6621                    });
 6622                    if !has_different_servers {
 6623                        if Some(cached_data.cache_version) == known_cache_version {
 6624                            return None;
 6625                        } else {
 6626                            return Some(
 6627                                Task::ready(Ok(DocumentColors {
 6628                                    colors: cached_data
 6629                                        .colors
 6630                                        .values()
 6631                                        .flatten()
 6632                                        .cloned()
 6633                                        .collect(),
 6634                                    cache_version: Some(cached_data.cache_version),
 6635                                }))
 6636                                .shared(),
 6637                            );
 6638                        }
 6639                    }
 6640                }
 6641            }
 6642        }
 6643
 6644        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6645        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6646            && !version_queried_for.changed_since(updating_for)
 6647        {
 6648            return Some(running_update.clone());
 6649        }
 6650        let query_version_queried_for = version_queried_for.clone();
 6651        let new_task = cx
 6652            .spawn(async move |lsp_store, cx| {
 6653                cx.background_executor()
 6654                    .timer(Duration::from_millis(30))
 6655                    .await;
 6656                let fetched_colors = lsp_store
 6657                    .update(cx, |lsp_store, cx| {
 6658                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6659                    })?
 6660                    .await
 6661                    .context("fetching document colors")
 6662                    .map_err(Arc::new);
 6663                let fetched_colors = match fetched_colors {
 6664                    Ok(fetched_colors) => {
 6665                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6666                            && Some(true)
 6667                                == buffer
 6668                                    .update(cx, |buffer, _| {
 6669                                        buffer.version() != query_version_queried_for
 6670                                    })
 6671                                    .ok()
 6672                        {
 6673                            return Ok(DocumentColors::default());
 6674                        }
 6675                        fetched_colors
 6676                    }
 6677                    Err(e) => {
 6678                        lsp_store
 6679                            .update(cx, |lsp_store, _| {
 6680                                lsp_store
 6681                                    .lsp_document_colors
 6682                                    .entry(buffer_id)
 6683                                    .or_default()
 6684                                    .colors_update = None;
 6685                            })
 6686                            .ok();
 6687                        return Err(e);
 6688                    }
 6689                };
 6690
 6691                lsp_store
 6692                    .update(cx, |lsp_store, _| {
 6693                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6694
 6695                        if let Some(fetched_colors) = fetched_colors {
 6696                            if lsp_data.colors_for_version == query_version_queried_for {
 6697                                lsp_data.colors.extend(fetched_colors);
 6698                                lsp_data.cache_version += 1;
 6699                            } else if !lsp_data
 6700                                .colors_for_version
 6701                                .changed_since(&query_version_queried_for)
 6702                            {
 6703                                lsp_data.colors_for_version = query_version_queried_for;
 6704                                lsp_data.colors = fetched_colors;
 6705                                lsp_data.cache_version += 1;
 6706                            }
 6707                        }
 6708                        lsp_data.colors_update = None;
 6709                        let colors = lsp_data
 6710                            .colors
 6711                            .values()
 6712                            .flatten()
 6713                            .cloned()
 6714                            .collect::<HashSet<_>>();
 6715                        DocumentColors {
 6716                            colors,
 6717                            cache_version: Some(lsp_data.cache_version),
 6718                        }
 6719                    })
 6720                    .map_err(Arc::new)
 6721            })
 6722            .shared();
 6723        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6724        Some(new_task)
 6725    }
 6726
 6727    fn fetch_document_colors_for_buffer(
 6728        &mut self,
 6729        buffer: &Entity<Buffer>,
 6730        cx: &mut Context<Self>,
 6731    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6732        if let Some((client, project_id)) = self.upstream_client() {
 6733            let request = GetDocumentColor {};
 6734            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6735                return Task::ready(Ok(None));
 6736            }
 6737
 6738            let request_task = client.request_lsp(
 6739                project_id,
 6740                LSP_REQUEST_TIMEOUT,
 6741                cx.background_executor().clone(),
 6742                request.to_proto(project_id, buffer.read(cx)),
 6743            );
 6744            let buffer = buffer.clone();
 6745            cx.spawn(async move |lsp_store, cx| {
 6746                let Some(project) = lsp_store.upgrade() else {
 6747                    return Ok(None);
 6748                };
 6749                let colors = join_all(
 6750                    request_task
 6751                        .await
 6752                        .log_err()
 6753                        .flatten()
 6754                        .map(|response| response.payload)
 6755                        .unwrap_or_default()
 6756                        .into_iter()
 6757                        .map(|color_response| {
 6758                            let response = request.response_from_proto(
 6759                                color_response.response,
 6760                                project.clone(),
 6761                                buffer.clone(),
 6762                                cx.clone(),
 6763                            );
 6764                            async move {
 6765                                (
 6766                                    LanguageServerId::from_proto(color_response.server_id),
 6767                                    response.await.log_err().unwrap_or_default(),
 6768                                )
 6769                            }
 6770                        }),
 6771                )
 6772                .await
 6773                .into_iter()
 6774                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6775                    acc.entry(server_id)
 6776                        .or_insert_with(HashSet::default)
 6777                        .extend(colors);
 6778                    acc
 6779                });
 6780                Ok(Some(colors))
 6781            })
 6782        } else {
 6783            let document_colors_task =
 6784                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6785            cx.background_spawn(async move {
 6786                Ok(Some(
 6787                    document_colors_task
 6788                        .await
 6789                        .into_iter()
 6790                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6791                            acc.entry(server_id)
 6792                                .or_insert_with(HashSet::default)
 6793                                .extend(colors);
 6794                            acc
 6795                        })
 6796                        .into_iter()
 6797                        .collect(),
 6798                ))
 6799            })
 6800        }
 6801    }
 6802
 6803    pub fn signature_help<T: ToPointUtf16>(
 6804        &mut self,
 6805        buffer: &Entity<Buffer>,
 6806        position: T,
 6807        cx: &mut Context<Self>,
 6808    ) -> Task<Option<Vec<SignatureHelp>>> {
 6809        let position = position.to_point_utf16(buffer.read(cx));
 6810
 6811        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6812            let request = GetSignatureHelp { position };
 6813            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6814                return Task::ready(None);
 6815            }
 6816            let request_task = client.request_lsp(
 6817                upstream_project_id,
 6818                LSP_REQUEST_TIMEOUT,
 6819                cx.background_executor().clone(),
 6820                request.to_proto(upstream_project_id, buffer.read(cx)),
 6821            );
 6822            let buffer = buffer.clone();
 6823            cx.spawn(async move |weak_project, cx| {
 6824                let project = weak_project.upgrade()?;
 6825                let signatures = join_all(
 6826                    request_task
 6827                        .await
 6828                        .log_err()
 6829                        .flatten()
 6830                        .map(|response| response.payload)
 6831                        .unwrap_or_default()
 6832                        .into_iter()
 6833                        .map(|response| {
 6834                            let response = GetSignatureHelp { position }.response_from_proto(
 6835                                response.response,
 6836                                project.clone(),
 6837                                buffer.clone(),
 6838                                cx.clone(),
 6839                            );
 6840                            async move { response.await.log_err().flatten() }
 6841                        }),
 6842                )
 6843                .await
 6844                .into_iter()
 6845                .flatten()
 6846                .collect();
 6847                Some(signatures)
 6848            })
 6849        } else {
 6850            let all_actions_task = self.request_multiple_lsp_locally(
 6851                buffer,
 6852                Some(position),
 6853                GetSignatureHelp { position },
 6854                cx,
 6855            );
 6856            cx.background_spawn(async move {
 6857                Some(
 6858                    all_actions_task
 6859                        .await
 6860                        .into_iter()
 6861                        .flat_map(|(_, actions)| actions)
 6862                        .collect::<Vec<_>>(),
 6863                )
 6864            })
 6865        }
 6866    }
 6867
 6868    pub fn hover(
 6869        &mut self,
 6870        buffer: &Entity<Buffer>,
 6871        position: PointUtf16,
 6872        cx: &mut Context<Self>,
 6873    ) -> Task<Option<Vec<Hover>>> {
 6874        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6875            let request = GetHover { position };
 6876            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6877                return Task::ready(None);
 6878            }
 6879            let request_task = client.request_lsp(
 6880                upstream_project_id,
 6881                LSP_REQUEST_TIMEOUT,
 6882                cx.background_executor().clone(),
 6883                request.to_proto(upstream_project_id, buffer.read(cx)),
 6884            );
 6885            let buffer = buffer.clone();
 6886            cx.spawn(async move |weak_project, cx| {
 6887                let project = weak_project.upgrade()?;
 6888                let hovers = join_all(
 6889                    request_task
 6890                        .await
 6891                        .log_err()
 6892                        .flatten()
 6893                        .map(|response| response.payload)
 6894                        .unwrap_or_default()
 6895                        .into_iter()
 6896                        .map(|response| {
 6897                            let response = GetHover { position }.response_from_proto(
 6898                                response.response,
 6899                                project.clone(),
 6900                                buffer.clone(),
 6901                                cx.clone(),
 6902                            );
 6903                            async move {
 6904                                response
 6905                                    .await
 6906                                    .log_err()
 6907                                    .flatten()
 6908                                    .and_then(remove_empty_hover_blocks)
 6909                            }
 6910                        }),
 6911                )
 6912                .await
 6913                .into_iter()
 6914                .flatten()
 6915                .collect();
 6916                Some(hovers)
 6917            })
 6918        } else {
 6919            let all_actions_task = self.request_multiple_lsp_locally(
 6920                buffer,
 6921                Some(position),
 6922                GetHover { position },
 6923                cx,
 6924            );
 6925            cx.background_spawn(async move {
 6926                Some(
 6927                    all_actions_task
 6928                        .await
 6929                        .into_iter()
 6930                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6931                        .collect::<Vec<Hover>>(),
 6932                )
 6933            })
 6934        }
 6935    }
 6936
 6937    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6938        let language_registry = self.languages.clone();
 6939
 6940        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6941            let request = upstream_client.request(proto::GetProjectSymbols {
 6942                project_id: *project_id,
 6943                query: query.to_string(),
 6944            });
 6945            cx.foreground_executor().spawn(async move {
 6946                let response = request.await?;
 6947                let mut symbols = Vec::new();
 6948                let core_symbols = response
 6949                    .symbols
 6950                    .into_iter()
 6951                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6952                    .collect::<Vec<_>>();
 6953                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6954                    .await;
 6955                Ok(symbols)
 6956            })
 6957        } else if let Some(local) = self.as_local() {
 6958            struct WorkspaceSymbolsResult {
 6959                server_id: LanguageServerId,
 6960                lsp_adapter: Arc<CachedLspAdapter>,
 6961                worktree: WeakEntity<Worktree>,
 6962                worktree_abs_path: Arc<Path>,
 6963                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6964            }
 6965
 6966            let mut requests = Vec::new();
 6967            let mut requested_servers = BTreeSet::new();
 6968            for (seed, state) in local.language_server_ids.iter() {
 6969                let Some(worktree_handle) = self
 6970                    .worktree_store
 6971                    .read(cx)
 6972                    .worktree_for_id(seed.worktree_id, cx)
 6973                else {
 6974                    continue;
 6975                };
 6976                let worktree = worktree_handle.read(cx);
 6977                if !worktree.is_visible() {
 6978                    continue;
 6979                }
 6980
 6981                if !requested_servers.insert(state.id) {
 6982                    continue;
 6983                }
 6984
 6985                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 6986                    Some(LanguageServerState::Running {
 6987                        adapter, server, ..
 6988                    }) => (adapter.clone(), server),
 6989
 6990                    _ => continue,
 6991                };
 6992                let supports_workspace_symbol_request =
 6993                    match server.capabilities().workspace_symbol_provider {
 6994                        Some(OneOf::Left(supported)) => supported,
 6995                        Some(OneOf::Right(_)) => true,
 6996                        None => false,
 6997                    };
 6998                if !supports_workspace_symbol_request {
 6999                    continue;
 7000                }
 7001                let worktree_abs_path = worktree.abs_path().clone();
 7002                let worktree_handle = worktree_handle.clone();
 7003                let server_id = server.server_id();
 7004                requests.push(
 7005                        server
 7006                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7007                                lsp::WorkspaceSymbolParams {
 7008                                    query: query.to_string(),
 7009                                    ..Default::default()
 7010                                },
 7011                            )
 7012                            .map(move |response| {
 7013                                let lsp_symbols = response.into_response()
 7014                                    .context("workspace symbols request")
 7015                                    .log_err()
 7016                                    .flatten()
 7017                                    .map(|symbol_response| match symbol_response {
 7018                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7019                                            flat_responses.into_iter().map(|lsp_symbol| {
 7020                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7021                                            }).collect::<Vec<_>>()
 7022                                        }
 7023                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7024                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7025                                                let location = match lsp_symbol.location {
 7026                                                    OneOf::Left(location) => location,
 7027                                                    OneOf::Right(_) => {
 7028                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7029                                                        return None
 7030                                                    }
 7031                                                };
 7032                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7033                                            }).collect::<Vec<_>>()
 7034                                        }
 7035                                    }).unwrap_or_default();
 7036
 7037                                WorkspaceSymbolsResult {
 7038                                    server_id,
 7039                                    lsp_adapter,
 7040                                    worktree: worktree_handle.downgrade(),
 7041                                    worktree_abs_path,
 7042                                    lsp_symbols,
 7043                                }
 7044                            }),
 7045                    );
 7046            }
 7047
 7048            cx.spawn(async move |this, cx| {
 7049                let responses = futures::future::join_all(requests).await;
 7050                let this = match this.upgrade() {
 7051                    Some(this) => this,
 7052                    None => return Ok(Vec::new()),
 7053                };
 7054
 7055                let mut symbols = Vec::new();
 7056                for result in responses {
 7057                    let core_symbols = this.update(cx, |this, cx| {
 7058                        result
 7059                            .lsp_symbols
 7060                            .into_iter()
 7061                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7062                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7063                                let source_worktree = result.worktree.upgrade()?;
 7064                                let source_worktree_id = source_worktree.read(cx).id();
 7065
 7066                                let path;
 7067                                let worktree;
 7068                                if let Some((tree, rel_path)) =
 7069                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7070                                {
 7071                                    worktree = tree;
 7072                                    path = rel_path;
 7073                                } else {
 7074                                    worktree = source_worktree;
 7075                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7076                                }
 7077
 7078                                let worktree_id = worktree.read(cx).id();
 7079                                let project_path = ProjectPath {
 7080                                    worktree_id,
 7081                                    path: path.into(),
 7082                                };
 7083                                let signature = this.symbol_signature(&project_path);
 7084                                Some(CoreSymbol {
 7085                                    source_language_server_id: result.server_id,
 7086                                    language_server_name: result.lsp_adapter.name.clone(),
 7087                                    source_worktree_id,
 7088                                    path: project_path,
 7089                                    kind: symbol_kind,
 7090                                    name: symbol_name,
 7091                                    range: range_from_lsp(symbol_location.range),
 7092                                    signature,
 7093                                })
 7094                            })
 7095                            .collect()
 7096                    })?;
 7097
 7098                    populate_labels_for_symbols(
 7099                        core_symbols,
 7100                        &language_registry,
 7101                        Some(result.lsp_adapter),
 7102                        &mut symbols,
 7103                    )
 7104                    .await;
 7105                }
 7106
 7107                Ok(symbols)
 7108            })
 7109        } else {
 7110            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7111        }
 7112    }
 7113
 7114    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7115        let mut summary = DiagnosticSummary::default();
 7116        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7117            summary.error_count += path_summary.error_count;
 7118            summary.warning_count += path_summary.warning_count;
 7119        }
 7120        summary
 7121    }
 7122
 7123    /// Returns the diagnostic summary for a specific project path.
 7124    pub fn diagnostic_summary_for_path(
 7125        &self,
 7126        project_path: &ProjectPath,
 7127        _: &App,
 7128    ) -> DiagnosticSummary {
 7129        if let Some(summaries) = self
 7130            .diagnostic_summaries
 7131            .get(&project_path.worktree_id)
 7132            .and_then(|map| map.get(&project_path.path))
 7133        {
 7134            let (error_count, warning_count) = summaries.iter().fold(
 7135                (0, 0),
 7136                |(error_count, warning_count), (_language_server_id, summary)| {
 7137                    (
 7138                        error_count + summary.error_count,
 7139                        warning_count + summary.warning_count,
 7140                    )
 7141                },
 7142            );
 7143
 7144            DiagnosticSummary {
 7145                error_count,
 7146                warning_count,
 7147            }
 7148        } else {
 7149            DiagnosticSummary::default()
 7150        }
 7151    }
 7152
 7153    pub fn diagnostic_summaries<'a>(
 7154        &'a self,
 7155        include_ignored: bool,
 7156        cx: &'a App,
 7157    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7158        self.worktree_store
 7159            .read(cx)
 7160            .visible_worktrees(cx)
 7161            .filter_map(|worktree| {
 7162                let worktree = worktree.read(cx);
 7163                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7164            })
 7165            .flat_map(move |(worktree, summaries)| {
 7166                let worktree_id = worktree.id();
 7167                summaries
 7168                    .iter()
 7169                    .filter(move |(path, _)| {
 7170                        include_ignored
 7171                            || worktree
 7172                                .entry_for_path(path.as_ref())
 7173                                .is_some_and(|entry| !entry.is_ignored)
 7174                    })
 7175                    .flat_map(move |(path, summaries)| {
 7176                        summaries.iter().map(move |(server_id, summary)| {
 7177                            (
 7178                                ProjectPath {
 7179                                    worktree_id,
 7180                                    path: path.clone(),
 7181                                },
 7182                                *server_id,
 7183                                *summary,
 7184                            )
 7185                        })
 7186                    })
 7187            })
 7188    }
 7189
 7190    pub fn on_buffer_edited(
 7191        &mut self,
 7192        buffer: Entity<Buffer>,
 7193        cx: &mut Context<Self>,
 7194    ) -> Option<()> {
 7195        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7196            Some(
 7197                self.as_local()?
 7198                    .language_servers_for_buffer(buffer, cx)
 7199                    .map(|i| i.1.clone())
 7200                    .collect(),
 7201            )
 7202        })?;
 7203
 7204        let buffer = buffer.read(cx);
 7205        let file = File::from_dyn(buffer.file())?;
 7206        let abs_path = file.as_local()?.abs_path(cx);
 7207        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7208        let next_snapshot = buffer.text_snapshot();
 7209        for language_server in language_servers {
 7210            let language_server = language_server.clone();
 7211
 7212            let buffer_snapshots = self
 7213                .as_local_mut()
 7214                .unwrap()
 7215                .buffer_snapshots
 7216                .get_mut(&buffer.remote_id())
 7217                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7218            let previous_snapshot = buffer_snapshots.last()?;
 7219
 7220            let build_incremental_change = || {
 7221                buffer
 7222                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7223                        previous_snapshot.snapshot.version(),
 7224                    )
 7225                    .map(|edit| {
 7226                        let edit_start = edit.new.start.0;
 7227                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7228                        let new_text = next_snapshot
 7229                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7230                            .collect();
 7231                        lsp::TextDocumentContentChangeEvent {
 7232                            range: Some(lsp::Range::new(
 7233                                point_to_lsp(edit_start),
 7234                                point_to_lsp(edit_end),
 7235                            )),
 7236                            range_length: None,
 7237                            text: new_text,
 7238                        }
 7239                    })
 7240                    .collect()
 7241            };
 7242
 7243            let document_sync_kind = language_server
 7244                .capabilities()
 7245                .text_document_sync
 7246                .as_ref()
 7247                .and_then(|sync| match sync {
 7248                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7249                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7250                });
 7251
 7252            let content_changes: Vec<_> = match document_sync_kind {
 7253                Some(lsp::TextDocumentSyncKind::FULL) => {
 7254                    vec![lsp::TextDocumentContentChangeEvent {
 7255                        range: None,
 7256                        range_length: None,
 7257                        text: next_snapshot.text(),
 7258                    }]
 7259                }
 7260                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7261                _ => {
 7262                    #[cfg(any(test, feature = "test-support"))]
 7263                    {
 7264                        build_incremental_change()
 7265                    }
 7266
 7267                    #[cfg(not(any(test, feature = "test-support")))]
 7268                    {
 7269                        continue;
 7270                    }
 7271                }
 7272            };
 7273
 7274            let next_version = previous_snapshot.version + 1;
 7275            buffer_snapshots.push(LspBufferSnapshot {
 7276                version: next_version,
 7277                snapshot: next_snapshot.clone(),
 7278            });
 7279
 7280            language_server
 7281                .notify::<lsp::notification::DidChangeTextDocument>(
 7282                    &lsp::DidChangeTextDocumentParams {
 7283                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7284                            uri.clone(),
 7285                            next_version,
 7286                        ),
 7287                        content_changes,
 7288                    },
 7289                )
 7290                .ok();
 7291            self.pull_workspace_diagnostics(language_server.server_id());
 7292        }
 7293
 7294        None
 7295    }
 7296
 7297    pub fn on_buffer_saved(
 7298        &mut self,
 7299        buffer: Entity<Buffer>,
 7300        cx: &mut Context<Self>,
 7301    ) -> Option<()> {
 7302        let file = File::from_dyn(buffer.read(cx).file())?;
 7303        let worktree_id = file.worktree_id(cx);
 7304        let abs_path = file.as_local()?.abs_path(cx);
 7305        let text_document = lsp::TextDocumentIdentifier {
 7306            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7307        };
 7308        let local = self.as_local()?;
 7309
 7310        for server in local.language_servers_for_worktree(worktree_id) {
 7311            if let Some(include_text) = include_text(server.as_ref()) {
 7312                let text = if include_text {
 7313                    Some(buffer.read(cx).text())
 7314                } else {
 7315                    None
 7316                };
 7317                server
 7318                    .notify::<lsp::notification::DidSaveTextDocument>(
 7319                        &lsp::DidSaveTextDocumentParams {
 7320                            text_document: text_document.clone(),
 7321                            text,
 7322                        },
 7323                    )
 7324                    .ok();
 7325            }
 7326        }
 7327
 7328        let language_servers = buffer.update(cx, |buffer, cx| {
 7329            local.language_server_ids_for_buffer(buffer, cx)
 7330        });
 7331        for language_server_id in language_servers {
 7332            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7333        }
 7334
 7335        None
 7336    }
 7337
 7338    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7339        maybe!(async move {
 7340            let mut refreshed_servers = HashSet::default();
 7341            let servers = lsp_store
 7342                .update(cx, |lsp_store, cx| {
 7343                    let local = lsp_store.as_local()?;
 7344
 7345                    let servers = local
 7346                        .language_server_ids
 7347                        .iter()
 7348                        .filter_map(|(seed, state)| {
 7349                            let worktree = lsp_store
 7350                                .worktree_store
 7351                                .read(cx)
 7352                                .worktree_for_id(seed.worktree_id, cx);
 7353                            let delegate: Arc<dyn LspAdapterDelegate> =
 7354                                worktree.map(|worktree| {
 7355                                    LocalLspAdapterDelegate::new(
 7356                                        local.languages.clone(),
 7357                                        &local.environment,
 7358                                        cx.weak_entity(),
 7359                                        &worktree,
 7360                                        local.http_client.clone(),
 7361                                        local.fs.clone(),
 7362                                        cx,
 7363                                    )
 7364                                })?;
 7365                            let server_id = state.id;
 7366
 7367                            let states = local.language_servers.get(&server_id)?;
 7368
 7369                            match states {
 7370                                LanguageServerState::Starting { .. } => None,
 7371                                LanguageServerState::Running {
 7372                                    adapter, server, ..
 7373                                } => {
 7374                                    let adapter = adapter.clone();
 7375                                    let server = server.clone();
 7376                                    refreshed_servers.insert(server.name());
 7377                                    let toolchain = seed.toolchain.clone();
 7378                                    Some(cx.spawn(async move |_, cx| {
 7379                                        let settings =
 7380                                            LocalLspStore::workspace_configuration_for_adapter(
 7381                                                adapter.adapter.clone(),
 7382                                                &delegate,
 7383                                                toolchain,
 7384                                                cx,
 7385                                            )
 7386                                            .await
 7387                                            .ok()?;
 7388                                        server
 7389                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7390                                                &lsp::DidChangeConfigurationParams { settings },
 7391                                            )
 7392                                            .ok()?;
 7393                                        Some(())
 7394                                    }))
 7395                                }
 7396                            }
 7397                        })
 7398                        .collect::<Vec<_>>();
 7399
 7400                    Some(servers)
 7401                })
 7402                .ok()
 7403                .flatten()?;
 7404
 7405            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7406            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7407            // to stop and unregister its language server wrapper.
 7408            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7409            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7410            let _: Vec<Option<()>> = join_all(servers).await;
 7411
 7412            Some(())
 7413        })
 7414        .await;
 7415    }
 7416
 7417    fn maintain_workspace_config(
 7418        external_refresh_requests: watch::Receiver<()>,
 7419        cx: &mut Context<Self>,
 7420    ) -> Task<Result<()>> {
 7421        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7422        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7423
 7424        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7425            *settings_changed_tx.borrow_mut() = ();
 7426        });
 7427
 7428        let mut joint_future =
 7429            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7430        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7431        // - 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).
 7432        // - 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.
 7433        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7434        // - 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,
 7435        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7436        cx.spawn(async move |this, cx| {
 7437            while let Some(()) = joint_future.next().await {
 7438                this.update(cx, |this, cx| {
 7439                    this.refresh_server_tree(cx);
 7440                })
 7441                .ok();
 7442
 7443                Self::refresh_workspace_configurations(&this, cx).await;
 7444            }
 7445
 7446            drop(settings_observation);
 7447            anyhow::Ok(())
 7448        })
 7449    }
 7450
 7451    pub fn language_servers_for_local_buffer<'a>(
 7452        &'a self,
 7453        buffer: &Buffer,
 7454        cx: &mut App,
 7455    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7456        let local = self.as_local();
 7457        let language_server_ids = local
 7458            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7459            .unwrap_or_default();
 7460
 7461        language_server_ids
 7462            .into_iter()
 7463            .filter_map(
 7464                move |server_id| match local?.language_servers.get(&server_id)? {
 7465                    LanguageServerState::Running {
 7466                        adapter, server, ..
 7467                    } => Some((adapter, server)),
 7468                    _ => None,
 7469                },
 7470            )
 7471    }
 7472
 7473    pub fn language_server_for_local_buffer<'a>(
 7474        &'a self,
 7475        buffer: &'a Buffer,
 7476        server_id: LanguageServerId,
 7477        cx: &'a mut App,
 7478    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7479        self.as_local()?
 7480            .language_servers_for_buffer(buffer, cx)
 7481            .find(|(_, s)| s.server_id() == server_id)
 7482    }
 7483
 7484    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7485        self.diagnostic_summaries.remove(&id_to_remove);
 7486        if let Some(local) = self.as_local_mut() {
 7487            let to_remove = local.remove_worktree(id_to_remove, cx);
 7488            for server in to_remove {
 7489                self.language_server_statuses.remove(&server);
 7490            }
 7491        }
 7492    }
 7493
 7494    pub fn shared(
 7495        &mut self,
 7496        project_id: u64,
 7497        downstream_client: AnyProtoClient,
 7498        _: &mut Context<Self>,
 7499    ) {
 7500        self.downstream_client = Some((downstream_client.clone(), project_id));
 7501
 7502        for (server_id, status) in &self.language_server_statuses {
 7503            if let Some(server) = self.language_server_for_id(*server_id) {
 7504                downstream_client
 7505                    .send(proto::StartLanguageServer {
 7506                        project_id,
 7507                        server: Some(proto::LanguageServer {
 7508                            id: server_id.to_proto(),
 7509                            name: status.name.to_string(),
 7510                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7511                        }),
 7512                        capabilities: serde_json::to_string(&server.capabilities())
 7513                            .expect("serializing server LSP capabilities"),
 7514                    })
 7515                    .log_err();
 7516            }
 7517        }
 7518    }
 7519
 7520    pub fn disconnected_from_host(&mut self) {
 7521        self.downstream_client.take();
 7522    }
 7523
 7524    pub fn disconnected_from_ssh_remote(&mut self) {
 7525        if let LspStoreMode::Remote(RemoteLspStore {
 7526            upstream_client, ..
 7527        }) = &mut self.mode
 7528        {
 7529            upstream_client.take();
 7530        }
 7531    }
 7532
 7533    pub(crate) fn set_language_server_statuses_from_proto(
 7534        &mut self,
 7535        project: WeakEntity<Project>,
 7536        language_servers: Vec<proto::LanguageServer>,
 7537        server_capabilities: Vec<String>,
 7538        cx: &mut Context<Self>,
 7539    ) {
 7540        let lsp_logs = cx
 7541            .try_global::<GlobalLogStore>()
 7542            .map(|lsp_store| lsp_store.0.clone());
 7543
 7544        self.language_server_statuses = language_servers
 7545            .into_iter()
 7546            .zip(server_capabilities)
 7547            .map(|(server, server_capabilities)| {
 7548                let server_id = LanguageServerId(server.id as usize);
 7549                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7550                    self.lsp_server_capabilities
 7551                        .insert(server_id, server_capabilities);
 7552                }
 7553
 7554                let name = LanguageServerName::from_proto(server.name);
 7555                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7556
 7557                if let Some(lsp_logs) = &lsp_logs {
 7558                    lsp_logs.update(cx, |lsp_logs, cx| {
 7559                        lsp_logs.add_language_server(
 7560                            // Only remote clients get their language servers set from proto
 7561                            LanguageServerKind::Remote {
 7562                                project: project.clone(),
 7563                            },
 7564                            server_id,
 7565                            Some(name.clone()),
 7566                            worktree,
 7567                            None,
 7568                            cx,
 7569                        );
 7570                    });
 7571                }
 7572
 7573                (
 7574                    server_id,
 7575                    LanguageServerStatus {
 7576                        name,
 7577                        pending_work: Default::default(),
 7578                        has_pending_diagnostic_updates: false,
 7579                        progress_tokens: Default::default(),
 7580                        worktree,
 7581                    },
 7582                )
 7583            })
 7584            .collect();
 7585    }
 7586
 7587    #[cfg(test)]
 7588    pub fn update_diagnostic_entries(
 7589        &mut self,
 7590        server_id: LanguageServerId,
 7591        abs_path: PathBuf,
 7592        result_id: Option<String>,
 7593        version: Option<i32>,
 7594        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7595        cx: &mut Context<Self>,
 7596    ) -> anyhow::Result<()> {
 7597        self.merge_diagnostic_entries(
 7598            vec![DocumentDiagnosticsUpdate {
 7599                diagnostics: DocumentDiagnostics {
 7600                    diagnostics,
 7601                    document_abs_path: abs_path,
 7602                    version,
 7603                },
 7604                result_id,
 7605                server_id,
 7606                disk_based_sources: Cow::Borrowed(&[]),
 7607            }],
 7608            |_, _, _| false,
 7609            cx,
 7610        )?;
 7611        Ok(())
 7612    }
 7613
 7614    pub fn merge_diagnostic_entries<'a>(
 7615        &mut self,
 7616        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7617        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7618        cx: &mut Context<Self>,
 7619    ) -> anyhow::Result<()> {
 7620        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7621        let mut updated_diagnostics_paths = HashMap::default();
 7622        for mut update in diagnostic_updates {
 7623            let abs_path = &update.diagnostics.document_abs_path;
 7624            let server_id = update.server_id;
 7625            let Some((worktree, relative_path)) =
 7626                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7627            else {
 7628                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7629                return Ok(());
 7630            };
 7631
 7632            let worktree_id = worktree.read(cx).id();
 7633            let project_path = ProjectPath {
 7634                worktree_id,
 7635                path: relative_path.into(),
 7636            };
 7637
 7638            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7639                let snapshot = buffer_handle.read(cx).snapshot();
 7640                let buffer = buffer_handle.read(cx);
 7641                let reused_diagnostics = buffer
 7642                    .buffer_diagnostics(Some(server_id))
 7643                    .iter()
 7644                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7645                    .map(|v| {
 7646                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7647                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7648                        DiagnosticEntry {
 7649                            range: start..end,
 7650                            diagnostic: v.diagnostic.clone(),
 7651                        }
 7652                    })
 7653                    .collect::<Vec<_>>();
 7654
 7655                self.as_local_mut()
 7656                    .context("cannot merge diagnostics on a remote LspStore")?
 7657                    .update_buffer_diagnostics(
 7658                        &buffer_handle,
 7659                        server_id,
 7660                        update.result_id,
 7661                        update.diagnostics.version,
 7662                        update.diagnostics.diagnostics.clone(),
 7663                        reused_diagnostics.clone(),
 7664                        cx,
 7665                    )?;
 7666
 7667                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7668            }
 7669
 7670            let updated = worktree.update(cx, |worktree, cx| {
 7671                self.update_worktree_diagnostics(
 7672                    worktree.id(),
 7673                    server_id,
 7674                    project_path.path.clone(),
 7675                    update.diagnostics.diagnostics,
 7676                    cx,
 7677                )
 7678            })?;
 7679            match updated {
 7680                ControlFlow::Continue(new_summary) => {
 7681                    if let Some((project_id, new_summary)) = new_summary {
 7682                        match &mut diagnostics_summary {
 7683                            Some(diagnostics_summary) => {
 7684                                diagnostics_summary
 7685                                    .more_summaries
 7686                                    .push(proto::DiagnosticSummary {
 7687                                        path: project_path.path.as_ref().to_proto(),
 7688                                        language_server_id: server_id.0 as u64,
 7689                                        error_count: new_summary.error_count,
 7690                                        warning_count: new_summary.warning_count,
 7691                                    })
 7692                            }
 7693                            None => {
 7694                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7695                                    project_id,
 7696                                    worktree_id: worktree_id.to_proto(),
 7697                                    summary: Some(proto::DiagnosticSummary {
 7698                                        path: project_path.path.as_ref().to_proto(),
 7699                                        language_server_id: server_id.0 as u64,
 7700                                        error_count: new_summary.error_count,
 7701                                        warning_count: new_summary.warning_count,
 7702                                    }),
 7703                                    more_summaries: Vec::new(),
 7704                                })
 7705                            }
 7706                        }
 7707                    }
 7708                    updated_diagnostics_paths
 7709                        .entry(server_id)
 7710                        .or_insert_with(Vec::new)
 7711                        .push(project_path);
 7712                }
 7713                ControlFlow::Break(()) => {}
 7714            }
 7715        }
 7716
 7717        if let Some((diagnostics_summary, (downstream_client, _))) =
 7718            diagnostics_summary.zip(self.downstream_client.as_ref())
 7719        {
 7720            downstream_client.send(diagnostics_summary).log_err();
 7721        }
 7722        for (server_id, paths) in updated_diagnostics_paths {
 7723            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7724        }
 7725        Ok(())
 7726    }
 7727
 7728    fn update_worktree_diagnostics(
 7729        &mut self,
 7730        worktree_id: WorktreeId,
 7731        server_id: LanguageServerId,
 7732        path_in_worktree: Arc<Path>,
 7733        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7734        _: &mut Context<Worktree>,
 7735    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7736        let local = match &mut self.mode {
 7737            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7738            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7739        };
 7740
 7741        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7742        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7743        let summaries_by_server_id = summaries_for_tree
 7744            .entry(path_in_worktree.clone())
 7745            .or_default();
 7746
 7747        let old_summary = summaries_by_server_id
 7748            .remove(&server_id)
 7749            .unwrap_or_default();
 7750
 7751        let new_summary = DiagnosticSummary::new(&diagnostics);
 7752        if new_summary.is_empty() {
 7753            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7754            {
 7755                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7756                    diagnostics_by_server_id.remove(ix);
 7757                }
 7758                if diagnostics_by_server_id.is_empty() {
 7759                    diagnostics_for_tree.remove(&path_in_worktree);
 7760                }
 7761            }
 7762        } else {
 7763            summaries_by_server_id.insert(server_id, new_summary);
 7764            let diagnostics_by_server_id = diagnostics_for_tree
 7765                .entry(path_in_worktree.clone())
 7766                .or_default();
 7767            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7768                Ok(ix) => {
 7769                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7770                }
 7771                Err(ix) => {
 7772                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7773                }
 7774            }
 7775        }
 7776
 7777        if !old_summary.is_empty() || !new_summary.is_empty() {
 7778            if let Some((_, project_id)) = &self.downstream_client {
 7779                Ok(ControlFlow::Continue(Some((
 7780                    *project_id,
 7781                    proto::DiagnosticSummary {
 7782                        path: path_in_worktree.to_proto(),
 7783                        language_server_id: server_id.0 as u64,
 7784                        error_count: new_summary.error_count as u32,
 7785                        warning_count: new_summary.warning_count as u32,
 7786                    },
 7787                ))))
 7788            } else {
 7789                Ok(ControlFlow::Continue(None))
 7790            }
 7791        } else {
 7792            Ok(ControlFlow::Break(()))
 7793        }
 7794    }
 7795
 7796    pub fn open_buffer_for_symbol(
 7797        &mut self,
 7798        symbol: &Symbol,
 7799        cx: &mut Context<Self>,
 7800    ) -> Task<Result<Entity<Buffer>>> {
 7801        if let Some((client, project_id)) = self.upstream_client() {
 7802            let request = client.request(proto::OpenBufferForSymbol {
 7803                project_id,
 7804                symbol: Some(Self::serialize_symbol(symbol)),
 7805            });
 7806            cx.spawn(async move |this, cx| {
 7807                let response = request.await?;
 7808                let buffer_id = BufferId::new(response.buffer_id)?;
 7809                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7810                    .await
 7811            })
 7812        } else if let Some(local) = self.as_local() {
 7813            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7814                seed.worktree_id == symbol.source_worktree_id
 7815                    && state.id == symbol.source_language_server_id
 7816                    && symbol.language_server_name == seed.name
 7817            });
 7818            if !is_valid {
 7819                return Task::ready(Err(anyhow!(
 7820                    "language server for worktree and language not found"
 7821                )));
 7822            };
 7823
 7824            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7825                .worktree_store
 7826                .read(cx)
 7827                .worktree_for_id(symbol.path.worktree_id, cx)
 7828                .map(|worktree| worktree.read(cx).abs_path())
 7829            {
 7830                worktree_abs_path
 7831            } else {
 7832                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7833            };
 7834
 7835            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7836            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7837                uri
 7838            } else {
 7839                return Task::ready(Err(anyhow!("invalid symbol path")));
 7840            };
 7841
 7842            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7843        } else {
 7844            Task::ready(Err(anyhow!("no upstream client or local store")))
 7845        }
 7846    }
 7847
 7848    pub(crate) fn open_local_buffer_via_lsp(
 7849        &mut self,
 7850        abs_path: lsp::Uri,
 7851        language_server_id: LanguageServerId,
 7852        cx: &mut Context<Self>,
 7853    ) -> Task<Result<Entity<Buffer>>> {
 7854        cx.spawn(async move |lsp_store, cx| {
 7855            // Escape percent-encoded string.
 7856            let current_scheme = abs_path.scheme().to_owned();
 7857            // Uri is immutable, so we can't modify the scheme
 7858
 7859            let abs_path = abs_path
 7860                .to_file_path()
 7861                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7862            let p = abs_path.clone();
 7863            let yarn_worktree = lsp_store
 7864                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7865                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7866                        cx.spawn(async move |this, cx| {
 7867                            let t = this
 7868                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7869                                .ok()?;
 7870                            t.await
 7871                        })
 7872                    }),
 7873                    None => Task::ready(None),
 7874                })?
 7875                .await;
 7876            let (worktree_root_target, known_relative_path) =
 7877                if let Some((zip_root, relative_path)) = yarn_worktree {
 7878                    (zip_root, Some(relative_path))
 7879                } else {
 7880                    (Arc::<Path>::from(abs_path.as_path()), None)
 7881                };
 7882            let (worktree, relative_path) = if let Some(result) =
 7883                lsp_store.update(cx, |lsp_store, cx| {
 7884                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7885                        worktree_store.find_worktree(&worktree_root_target, cx)
 7886                    })
 7887                })? {
 7888                let relative_path =
 7889                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7890                (result.0, relative_path)
 7891            } else {
 7892                let worktree = lsp_store
 7893                    .update(cx, |lsp_store, cx| {
 7894                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7895                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7896                        })
 7897                    })?
 7898                    .await?;
 7899                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7900                    lsp_store
 7901                        .update(cx, |lsp_store, cx| {
 7902                            if let Some(local) = lsp_store.as_local_mut() {
 7903                                local.register_language_server_for_invisible_worktree(
 7904                                    &worktree,
 7905                                    language_server_id,
 7906                                    cx,
 7907                                )
 7908                            }
 7909                        })
 7910                        .ok();
 7911                }
 7912                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7913                let relative_path = if let Some(known_path) = known_relative_path {
 7914                    known_path
 7915                } else {
 7916                    abs_path.strip_prefix(worktree_root)?.into()
 7917                };
 7918                (worktree, relative_path)
 7919            };
 7920            let project_path = ProjectPath {
 7921                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7922                path: relative_path,
 7923            };
 7924            lsp_store
 7925                .update(cx, |lsp_store, cx| {
 7926                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7927                        buffer_store.open_buffer(project_path, cx)
 7928                    })
 7929                })?
 7930                .await
 7931        })
 7932    }
 7933
 7934    fn request_multiple_lsp_locally<P, R>(
 7935        &mut self,
 7936        buffer: &Entity<Buffer>,
 7937        position: Option<P>,
 7938        request: R,
 7939        cx: &mut Context<Self>,
 7940    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7941    where
 7942        P: ToOffset,
 7943        R: LspCommand + Clone,
 7944        <R::LspRequest as lsp::request::Request>::Result: Send,
 7945        <R::LspRequest as lsp::request::Request>::Params: Send,
 7946    {
 7947        let Some(local) = self.as_local() else {
 7948            return Task::ready(Vec::new());
 7949        };
 7950
 7951        let snapshot = buffer.read(cx).snapshot();
 7952        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7953
 7954        let server_ids = buffer.update(cx, |buffer, cx| {
 7955            local
 7956                .language_servers_for_buffer(buffer, cx)
 7957                .filter(|(adapter, _)| {
 7958                    scope
 7959                        .as_ref()
 7960                        .map(|scope| scope.language_allowed(&adapter.name))
 7961                        .unwrap_or(true)
 7962                })
 7963                .map(|(_, server)| server.server_id())
 7964                .filter(|server_id| {
 7965                    self.as_local().is_none_or(|local| {
 7966                        local
 7967                            .buffers_opened_in_servers
 7968                            .get(&snapshot.remote_id())
 7969                            .is_some_and(|servers| servers.contains(server_id))
 7970                    })
 7971                })
 7972                .collect::<Vec<_>>()
 7973        });
 7974
 7975        let mut response_results = server_ids
 7976            .into_iter()
 7977            .map(|server_id| {
 7978                let task = self.request_lsp(
 7979                    buffer.clone(),
 7980                    LanguageServerToQuery::Other(server_id),
 7981                    request.clone(),
 7982                    cx,
 7983                );
 7984                async move { (server_id, task.await) }
 7985            })
 7986            .collect::<FuturesUnordered<_>>();
 7987
 7988        cx.background_spawn(async move {
 7989            let mut responses = Vec::with_capacity(response_results.len());
 7990            while let Some((server_id, response_result)) = response_results.next().await {
 7991                if let Some(response) = response_result.log_err() {
 7992                    responses.push((server_id, response));
 7993                }
 7994            }
 7995            responses
 7996        })
 7997    }
 7998
 7999    async fn handle_lsp_command<T: LspCommand>(
 8000        this: Entity<Self>,
 8001        envelope: TypedEnvelope<T::ProtoRequest>,
 8002        mut cx: AsyncApp,
 8003    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8004    where
 8005        <T::LspRequest as lsp::request::Request>::Params: Send,
 8006        <T::LspRequest as lsp::request::Request>::Result: Send,
 8007    {
 8008        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8009        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8010        let buffer_handle = this.update(&mut cx, |this, cx| {
 8011            this.buffer_store.read(cx).get_existing(buffer_id)
 8012        })??;
 8013        let request = T::from_proto(
 8014            envelope.payload,
 8015            this.clone(),
 8016            buffer_handle.clone(),
 8017            cx.clone(),
 8018        )
 8019        .await?;
 8020        let response = this
 8021            .update(&mut cx, |this, cx| {
 8022                this.request_lsp(
 8023                    buffer_handle.clone(),
 8024                    LanguageServerToQuery::FirstCapable,
 8025                    request,
 8026                    cx,
 8027                )
 8028            })?
 8029            .await?;
 8030        this.update(&mut cx, |this, cx| {
 8031            Ok(T::response_to_proto(
 8032                response,
 8033                this,
 8034                sender_id,
 8035                &buffer_handle.read(cx).version(),
 8036                cx,
 8037            ))
 8038        })?
 8039    }
 8040
 8041    async fn handle_lsp_query(
 8042        lsp_store: Entity<Self>,
 8043        envelope: TypedEnvelope<proto::LspQuery>,
 8044        mut cx: AsyncApp,
 8045    ) -> Result<proto::Ack> {
 8046        use proto::lsp_query::Request;
 8047        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8048        let lsp_query = envelope.payload;
 8049        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8050        match lsp_query.request.context("invalid LSP query request")? {
 8051            Request::GetReferences(get_references) => {
 8052                let position = get_references.position.clone().and_then(deserialize_anchor);
 8053                Self::query_lsp_locally::<GetReferences>(
 8054                    lsp_store,
 8055                    sender_id,
 8056                    lsp_request_id,
 8057                    get_references,
 8058                    position,
 8059                    cx.clone(),
 8060                )
 8061                .await?;
 8062            }
 8063            Request::GetDocumentColor(get_document_color) => {
 8064                Self::query_lsp_locally::<GetDocumentColor>(
 8065                    lsp_store,
 8066                    sender_id,
 8067                    lsp_request_id,
 8068                    get_document_color,
 8069                    None,
 8070                    cx.clone(),
 8071                )
 8072                .await?;
 8073            }
 8074            Request::GetHover(get_hover) => {
 8075                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8076                Self::query_lsp_locally::<GetHover>(
 8077                    lsp_store,
 8078                    sender_id,
 8079                    lsp_request_id,
 8080                    get_hover,
 8081                    position,
 8082                    cx.clone(),
 8083                )
 8084                .await?;
 8085            }
 8086            Request::GetCodeActions(get_code_actions) => {
 8087                Self::query_lsp_locally::<GetCodeActions>(
 8088                    lsp_store,
 8089                    sender_id,
 8090                    lsp_request_id,
 8091                    get_code_actions,
 8092                    None,
 8093                    cx.clone(),
 8094                )
 8095                .await?;
 8096            }
 8097            Request::GetSignatureHelp(get_signature_help) => {
 8098                let position = get_signature_help
 8099                    .position
 8100                    .clone()
 8101                    .and_then(deserialize_anchor);
 8102                Self::query_lsp_locally::<GetSignatureHelp>(
 8103                    lsp_store,
 8104                    sender_id,
 8105                    lsp_request_id,
 8106                    get_signature_help,
 8107                    position,
 8108                    cx.clone(),
 8109                )
 8110                .await?;
 8111            }
 8112            Request::GetCodeLens(get_code_lens) => {
 8113                Self::query_lsp_locally::<GetCodeLens>(
 8114                    lsp_store,
 8115                    sender_id,
 8116                    lsp_request_id,
 8117                    get_code_lens,
 8118                    None,
 8119                    cx.clone(),
 8120                )
 8121                .await?;
 8122            }
 8123            Request::GetDefinition(get_definition) => {
 8124                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8125                Self::query_lsp_locally::<GetDefinitions>(
 8126                    lsp_store,
 8127                    sender_id,
 8128                    lsp_request_id,
 8129                    get_definition,
 8130                    position,
 8131                    cx.clone(),
 8132                )
 8133                .await?;
 8134            }
 8135            Request::GetDeclaration(get_declaration) => {
 8136                let position = get_declaration
 8137                    .position
 8138                    .clone()
 8139                    .and_then(deserialize_anchor);
 8140                Self::query_lsp_locally::<GetDeclarations>(
 8141                    lsp_store,
 8142                    sender_id,
 8143                    lsp_request_id,
 8144                    get_declaration,
 8145                    position,
 8146                    cx.clone(),
 8147                )
 8148                .await?;
 8149            }
 8150            Request::GetTypeDefinition(get_type_definition) => {
 8151                let position = get_type_definition
 8152                    .position
 8153                    .clone()
 8154                    .and_then(deserialize_anchor);
 8155                Self::query_lsp_locally::<GetTypeDefinitions>(
 8156                    lsp_store,
 8157                    sender_id,
 8158                    lsp_request_id,
 8159                    get_type_definition,
 8160                    position,
 8161                    cx.clone(),
 8162                )
 8163                .await?;
 8164            }
 8165            Request::GetImplementation(get_implementation) => {
 8166                let position = get_implementation
 8167                    .position
 8168                    .clone()
 8169                    .and_then(deserialize_anchor);
 8170                Self::query_lsp_locally::<GetImplementations>(
 8171                    lsp_store,
 8172                    sender_id,
 8173                    lsp_request_id,
 8174                    get_implementation,
 8175                    position,
 8176                    cx.clone(),
 8177                )
 8178                .await?;
 8179            }
 8180            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8181            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8182                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8183                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8184                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8185                    this.buffer_store.read(cx).get_existing(buffer_id)
 8186                })??;
 8187                buffer
 8188                    .update(&mut cx, |buffer, _| {
 8189                        buffer.wait_for_version(version.clone())
 8190                    })?
 8191                    .await?;
 8192                lsp_store.update(&mut cx, |lsp_store, cx| {
 8193                    let existing_queries = lsp_store
 8194                        .running_lsp_requests
 8195                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8196                        .or_default();
 8197                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8198                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8199                    {
 8200                        existing_queries.1.clear();
 8201                    }
 8202                    existing_queries.1.insert(
 8203                        lsp_request_id,
 8204                        cx.spawn(async move |lsp_store, cx| {
 8205                            let diagnostics_pull = lsp_store
 8206                                .update(cx, |lsp_store, cx| {
 8207                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8208                                })
 8209                                .ok();
 8210                            if let Some(diagnostics_pull) = diagnostics_pull {
 8211                                match diagnostics_pull.await {
 8212                                    Ok(()) => {}
 8213                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8214                                };
 8215                            }
 8216                        }),
 8217                    );
 8218                })?;
 8219            }
 8220        }
 8221        Ok(proto::Ack {})
 8222    }
 8223
 8224    async fn handle_lsp_query_response(
 8225        lsp_store: Entity<Self>,
 8226        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8227        cx: AsyncApp,
 8228    ) -> Result<()> {
 8229        lsp_store.read_with(&cx, |lsp_store, _| {
 8230            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8231                upstream_client.handle_lsp_response(envelope.clone());
 8232            }
 8233        })?;
 8234        Ok(())
 8235    }
 8236
 8237    async fn handle_apply_code_action(
 8238        this: Entity<Self>,
 8239        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8240        mut cx: AsyncApp,
 8241    ) -> Result<proto::ApplyCodeActionResponse> {
 8242        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8243        let action =
 8244            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8245        let apply_code_action = this.update(&mut cx, |this, cx| {
 8246            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8247            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8248            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8249        })??;
 8250
 8251        let project_transaction = apply_code_action.await?;
 8252        let project_transaction = this.update(&mut cx, |this, cx| {
 8253            this.buffer_store.update(cx, |buffer_store, cx| {
 8254                buffer_store.serialize_project_transaction_for_peer(
 8255                    project_transaction,
 8256                    sender_id,
 8257                    cx,
 8258                )
 8259            })
 8260        })?;
 8261        Ok(proto::ApplyCodeActionResponse {
 8262            transaction: Some(project_transaction),
 8263        })
 8264    }
 8265
 8266    async fn handle_register_buffer_with_language_servers(
 8267        this: Entity<Self>,
 8268        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8269        mut cx: AsyncApp,
 8270    ) -> Result<proto::Ack> {
 8271        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8272        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8273        this.update(&mut cx, |this, cx| {
 8274            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8275                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8276                    project_id: upstream_project_id,
 8277                    buffer_id: buffer_id.to_proto(),
 8278                    only_servers: envelope.payload.only_servers,
 8279                });
 8280            }
 8281
 8282            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8283                anyhow::bail!("buffer is not open");
 8284            };
 8285
 8286            let handle = this.register_buffer_with_language_servers(
 8287                &buffer,
 8288                envelope
 8289                    .payload
 8290                    .only_servers
 8291                    .into_iter()
 8292                    .filter_map(|selector| {
 8293                        Some(match selector.selector? {
 8294                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8295                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8296                            }
 8297                            proto::language_server_selector::Selector::Name(name) => {
 8298                                LanguageServerSelector::Name(LanguageServerName(
 8299                                    SharedString::from(name),
 8300                                ))
 8301                            }
 8302                        })
 8303                    })
 8304                    .collect(),
 8305                false,
 8306                cx,
 8307            );
 8308            this.buffer_store().update(cx, |buffer_store, _| {
 8309                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8310            });
 8311
 8312            Ok(())
 8313        })??;
 8314        Ok(proto::Ack {})
 8315    }
 8316
 8317    async fn handle_rename_project_entry(
 8318        this: Entity<Self>,
 8319        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8320        mut cx: AsyncApp,
 8321    ) -> Result<proto::ProjectEntryResponse> {
 8322        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8323        let (worktree_id, worktree, old_path, is_dir) = this
 8324            .update(&mut cx, |this, cx| {
 8325                this.worktree_store
 8326                    .read(cx)
 8327                    .worktree_and_entry_for_id(entry_id, cx)
 8328                    .map(|(worktree, entry)| {
 8329                        (
 8330                            worktree.read(cx).id(),
 8331                            worktree,
 8332                            entry.path.clone(),
 8333                            entry.is_dir(),
 8334                        )
 8335                    })
 8336            })?
 8337            .context("worktree not found")?;
 8338        let (old_abs_path, new_abs_path) = {
 8339            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8340            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8341            (root_path.join(&old_path), root_path.join(&new_path))
 8342        };
 8343
 8344        let _transaction = Self::will_rename_entry(
 8345            this.downgrade(),
 8346            worktree_id,
 8347            &old_abs_path,
 8348            &new_abs_path,
 8349            is_dir,
 8350            cx.clone(),
 8351        )
 8352        .await;
 8353        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8354        this.read_with(&cx, |this, _| {
 8355            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8356        })
 8357        .ok();
 8358        response
 8359    }
 8360
 8361    async fn handle_update_diagnostic_summary(
 8362        this: Entity<Self>,
 8363        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8364        mut cx: AsyncApp,
 8365    ) -> Result<()> {
 8366        this.update(&mut cx, |lsp_store, cx| {
 8367            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8368            let mut updated_diagnostics_paths = HashMap::default();
 8369            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8370            for message_summary in envelope
 8371                .payload
 8372                .summary
 8373                .into_iter()
 8374                .chain(envelope.payload.more_summaries)
 8375            {
 8376                let project_path = ProjectPath {
 8377                    worktree_id,
 8378                    path: Arc::<Path>::from_proto(message_summary.path),
 8379                };
 8380                let path = project_path.path.clone();
 8381                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8382                let summary = DiagnosticSummary {
 8383                    error_count: message_summary.error_count as usize,
 8384                    warning_count: message_summary.warning_count as usize,
 8385                };
 8386
 8387                if summary.is_empty() {
 8388                    if let Some(worktree_summaries) =
 8389                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8390                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8391                    {
 8392                        summaries.remove(&server_id);
 8393                        if summaries.is_empty() {
 8394                            worktree_summaries.remove(&path);
 8395                        }
 8396                    }
 8397                } else {
 8398                    lsp_store
 8399                        .diagnostic_summaries
 8400                        .entry(worktree_id)
 8401                        .or_default()
 8402                        .entry(path)
 8403                        .or_default()
 8404                        .insert(server_id, summary);
 8405                }
 8406
 8407                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8408                    match &mut diagnostics_summary {
 8409                        Some(diagnostics_summary) => {
 8410                            diagnostics_summary
 8411                                .more_summaries
 8412                                .push(proto::DiagnosticSummary {
 8413                                    path: project_path.path.as_ref().to_proto(),
 8414                                    language_server_id: server_id.0 as u64,
 8415                                    error_count: summary.error_count as u32,
 8416                                    warning_count: summary.warning_count as u32,
 8417                                })
 8418                        }
 8419                        None => {
 8420                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8421                                project_id: *project_id,
 8422                                worktree_id: worktree_id.to_proto(),
 8423                                summary: Some(proto::DiagnosticSummary {
 8424                                    path: project_path.path.as_ref().to_proto(),
 8425                                    language_server_id: server_id.0 as u64,
 8426                                    error_count: summary.error_count as u32,
 8427                                    warning_count: summary.warning_count as u32,
 8428                                }),
 8429                                more_summaries: Vec::new(),
 8430                            })
 8431                        }
 8432                    }
 8433                }
 8434                updated_diagnostics_paths
 8435                    .entry(server_id)
 8436                    .or_insert_with(Vec::new)
 8437                    .push(project_path);
 8438            }
 8439
 8440            if let Some((diagnostics_summary, (downstream_client, _))) =
 8441                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8442            {
 8443                downstream_client.send(diagnostics_summary).log_err();
 8444            }
 8445            for (server_id, paths) in updated_diagnostics_paths {
 8446                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8447            }
 8448            Ok(())
 8449        })?
 8450    }
 8451
 8452    async fn handle_start_language_server(
 8453        lsp_store: Entity<Self>,
 8454        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8455        mut cx: AsyncApp,
 8456    ) -> Result<()> {
 8457        let server = envelope.payload.server.context("invalid server")?;
 8458        let server_capabilities =
 8459            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8460                .with_context(|| {
 8461                    format!(
 8462                        "incorrect server capabilities {}",
 8463                        envelope.payload.capabilities
 8464                    )
 8465                })?;
 8466        lsp_store.update(&mut cx, |lsp_store, cx| {
 8467            let server_id = LanguageServerId(server.id as usize);
 8468            let server_name = LanguageServerName::from_proto(server.name.clone());
 8469            lsp_store
 8470                .lsp_server_capabilities
 8471                .insert(server_id, server_capabilities);
 8472            lsp_store.language_server_statuses.insert(
 8473                server_id,
 8474                LanguageServerStatus {
 8475                    name: server_name.clone(),
 8476                    pending_work: Default::default(),
 8477                    has_pending_diagnostic_updates: false,
 8478                    progress_tokens: Default::default(),
 8479                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8480                },
 8481            );
 8482            cx.emit(LspStoreEvent::LanguageServerAdded(
 8483                server_id,
 8484                server_name,
 8485                server.worktree_id.map(WorktreeId::from_proto),
 8486            ));
 8487            cx.notify();
 8488        })?;
 8489        Ok(())
 8490    }
 8491
 8492    async fn handle_update_language_server(
 8493        lsp_store: Entity<Self>,
 8494        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8495        mut cx: AsyncApp,
 8496    ) -> Result<()> {
 8497        lsp_store.update(&mut cx, |lsp_store, cx| {
 8498            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8499
 8500            match envelope.payload.variant.context("invalid variant")? {
 8501                proto::update_language_server::Variant::WorkStart(payload) => {
 8502                    lsp_store.on_lsp_work_start(
 8503                        language_server_id,
 8504                        payload.token,
 8505                        LanguageServerProgress {
 8506                            title: payload.title,
 8507                            is_disk_based_diagnostics_progress: false,
 8508                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8509                            message: payload.message,
 8510                            percentage: payload.percentage.map(|p| p as usize),
 8511                            last_update_at: cx.background_executor().now(),
 8512                        },
 8513                        cx,
 8514                    );
 8515                }
 8516                proto::update_language_server::Variant::WorkProgress(payload) => {
 8517                    lsp_store.on_lsp_work_progress(
 8518                        language_server_id,
 8519                        payload.token,
 8520                        LanguageServerProgress {
 8521                            title: None,
 8522                            is_disk_based_diagnostics_progress: false,
 8523                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8524                            message: payload.message,
 8525                            percentage: payload.percentage.map(|p| p as usize),
 8526                            last_update_at: cx.background_executor().now(),
 8527                        },
 8528                        cx,
 8529                    );
 8530                }
 8531
 8532                proto::update_language_server::Variant::WorkEnd(payload) => {
 8533                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8534                }
 8535
 8536                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8537                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8538                }
 8539
 8540                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8541                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8542                }
 8543
 8544                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8545                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8546                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8547                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8548                        language_server_id,
 8549                        name: envelope
 8550                            .payload
 8551                            .server_name
 8552                            .map(SharedString::new)
 8553                            .map(LanguageServerName),
 8554                        message: non_lsp,
 8555                    });
 8556                }
 8557            }
 8558
 8559            Ok(())
 8560        })?
 8561    }
 8562
 8563    async fn handle_language_server_log(
 8564        this: Entity<Self>,
 8565        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8566        mut cx: AsyncApp,
 8567    ) -> Result<()> {
 8568        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8569        let log_type = envelope
 8570            .payload
 8571            .log_type
 8572            .map(LanguageServerLogType::from_proto)
 8573            .context("invalid language server log type")?;
 8574
 8575        let message = envelope.payload.message;
 8576
 8577        this.update(&mut cx, |_, cx| {
 8578            cx.emit(LspStoreEvent::LanguageServerLog(
 8579                language_server_id,
 8580                log_type,
 8581                message,
 8582            ));
 8583        })
 8584    }
 8585
 8586    async fn handle_lsp_ext_cancel_flycheck(
 8587        lsp_store: Entity<Self>,
 8588        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 8589        cx: AsyncApp,
 8590    ) -> Result<proto::Ack> {
 8591        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8592        lsp_store.read_with(&cx, |lsp_store, _| {
 8593            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8594                server
 8595                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 8596                    .context("handling lsp ext cancel flycheck")
 8597            } else {
 8598                anyhow::Ok(())
 8599            }
 8600        })??;
 8601
 8602        Ok(proto::Ack {})
 8603    }
 8604
 8605    async fn handle_lsp_ext_run_flycheck(
 8606        lsp_store: Entity<Self>,
 8607        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 8608        mut cx: AsyncApp,
 8609    ) -> Result<proto::Ack> {
 8610        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8611        lsp_store.update(&mut cx, |lsp_store, cx| {
 8612            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8613                let text_document = if envelope.payload.current_file_only {
 8614                    let buffer_id = envelope
 8615                        .payload
 8616                        .buffer_id
 8617                        .map(|id| BufferId::new(id))
 8618                        .transpose()?;
 8619                    buffer_id
 8620                        .and_then(|buffer_id| {
 8621                            lsp_store
 8622                                .buffer_store()
 8623                                .read(cx)
 8624                                .get(buffer_id)
 8625                                .and_then(|buffer| {
 8626                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 8627                                })
 8628                                .map(|path| make_text_document_identifier(&path))
 8629                        })
 8630                        .transpose()?
 8631                } else {
 8632                    None
 8633                };
 8634                server
 8635                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 8636                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 8637                    )
 8638                    .context("handling lsp ext run flycheck")
 8639            } else {
 8640                anyhow::Ok(())
 8641            }
 8642        })??;
 8643
 8644        Ok(proto::Ack {})
 8645    }
 8646
 8647    async fn handle_lsp_ext_clear_flycheck(
 8648        lsp_store: Entity<Self>,
 8649        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 8650        cx: AsyncApp,
 8651    ) -> Result<proto::Ack> {
 8652        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8653        lsp_store.read_with(&cx, |lsp_store, _| {
 8654            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8655                server
 8656                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 8657                    .context("handling lsp ext clear flycheck")
 8658            } else {
 8659                anyhow::Ok(())
 8660            }
 8661        })??;
 8662
 8663        Ok(proto::Ack {})
 8664    }
 8665
 8666    pub fn disk_based_diagnostics_started(
 8667        &mut self,
 8668        language_server_id: LanguageServerId,
 8669        cx: &mut Context<Self>,
 8670    ) {
 8671        if let Some(language_server_status) =
 8672            self.language_server_statuses.get_mut(&language_server_id)
 8673        {
 8674            language_server_status.has_pending_diagnostic_updates = true;
 8675        }
 8676
 8677        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 8678        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8679            language_server_id,
 8680            name: self
 8681                .language_server_adapter_for_id(language_server_id)
 8682                .map(|adapter| adapter.name()),
 8683            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 8684                Default::default(),
 8685            ),
 8686        })
 8687    }
 8688
 8689    pub fn disk_based_diagnostics_finished(
 8690        &mut self,
 8691        language_server_id: LanguageServerId,
 8692        cx: &mut Context<Self>,
 8693    ) {
 8694        if let Some(language_server_status) =
 8695            self.language_server_statuses.get_mut(&language_server_id)
 8696        {
 8697            language_server_status.has_pending_diagnostic_updates = false;
 8698        }
 8699
 8700        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 8701        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8702            language_server_id,
 8703            name: self
 8704                .language_server_adapter_for_id(language_server_id)
 8705                .map(|adapter| adapter.name()),
 8706            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 8707                Default::default(),
 8708            ),
 8709        })
 8710    }
 8711
 8712    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 8713    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 8714    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 8715    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 8716    // the language server might take some time to publish diagnostics.
 8717    fn simulate_disk_based_diagnostics_events_if_needed(
 8718        &mut self,
 8719        language_server_id: LanguageServerId,
 8720        cx: &mut Context<Self>,
 8721    ) {
 8722        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 8723
 8724        let Some(LanguageServerState::Running {
 8725            simulate_disk_based_diagnostics_completion,
 8726            adapter,
 8727            ..
 8728        }) = self
 8729            .as_local_mut()
 8730            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 8731        else {
 8732            return;
 8733        };
 8734
 8735        if adapter.disk_based_diagnostics_progress_token.is_some() {
 8736            return;
 8737        }
 8738
 8739        let prev_task =
 8740            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 8741                cx.background_executor()
 8742                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 8743                    .await;
 8744
 8745                this.update(cx, |this, cx| {
 8746                    this.disk_based_diagnostics_finished(language_server_id, cx);
 8747
 8748                    if let Some(LanguageServerState::Running {
 8749                        simulate_disk_based_diagnostics_completion,
 8750                        ..
 8751                    }) = this.as_local_mut().and_then(|local_store| {
 8752                        local_store.language_servers.get_mut(&language_server_id)
 8753                    }) {
 8754                        *simulate_disk_based_diagnostics_completion = None;
 8755                    }
 8756                })
 8757                .ok();
 8758            }));
 8759
 8760        if prev_task.is_none() {
 8761            self.disk_based_diagnostics_started(language_server_id, cx);
 8762        }
 8763    }
 8764
 8765    pub fn language_server_statuses(
 8766        &self,
 8767    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 8768        self.language_server_statuses
 8769            .iter()
 8770            .map(|(key, value)| (*key, value))
 8771    }
 8772
 8773    pub(super) fn did_rename_entry(
 8774        &self,
 8775        worktree_id: WorktreeId,
 8776        old_path: &Path,
 8777        new_path: &Path,
 8778        is_dir: bool,
 8779    ) {
 8780        maybe!({
 8781            let local_store = self.as_local()?;
 8782
 8783            let old_uri = lsp::Uri::from_file_path(old_path)
 8784                .ok()
 8785                .map(|uri| uri.to_string())?;
 8786            let new_uri = lsp::Uri::from_file_path(new_path)
 8787                .ok()
 8788                .map(|uri| uri.to_string())?;
 8789
 8790            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8791                let Some(filter) = local_store
 8792                    .language_server_paths_watched_for_rename
 8793                    .get(&language_server.server_id())
 8794                else {
 8795                    continue;
 8796                };
 8797
 8798                if filter.should_send_did_rename(&old_uri, is_dir) {
 8799                    language_server
 8800                        .notify::<DidRenameFiles>(&RenameFilesParams {
 8801                            files: vec![FileRename {
 8802                                old_uri: old_uri.clone(),
 8803                                new_uri: new_uri.clone(),
 8804                            }],
 8805                        })
 8806                        .ok();
 8807                }
 8808            }
 8809            Some(())
 8810        });
 8811    }
 8812
 8813    pub(super) fn will_rename_entry(
 8814        this: WeakEntity<Self>,
 8815        worktree_id: WorktreeId,
 8816        old_path: &Path,
 8817        new_path: &Path,
 8818        is_dir: bool,
 8819        cx: AsyncApp,
 8820    ) -> Task<ProjectTransaction> {
 8821        let old_uri = lsp::Uri::from_file_path(old_path)
 8822            .ok()
 8823            .map(|uri| uri.to_string());
 8824        let new_uri = lsp::Uri::from_file_path(new_path)
 8825            .ok()
 8826            .map(|uri| uri.to_string());
 8827        cx.spawn(async move |cx| {
 8828            let mut tasks = vec![];
 8829            this.update(cx, |this, cx| {
 8830                let local_store = this.as_local()?;
 8831                let old_uri = old_uri?;
 8832                let new_uri = new_uri?;
 8833                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8834                    let Some(filter) = local_store
 8835                        .language_server_paths_watched_for_rename
 8836                        .get(&language_server.server_id())
 8837                    else {
 8838                        continue;
 8839                    };
 8840
 8841                    if filter.should_send_will_rename(&old_uri, is_dir) {
 8842                        let apply_edit = cx.spawn({
 8843                            let old_uri = old_uri.clone();
 8844                            let new_uri = new_uri.clone();
 8845                            let language_server = language_server.clone();
 8846                            async move |this, cx| {
 8847                                let edit = language_server
 8848                                    .request::<WillRenameFiles>(RenameFilesParams {
 8849                                        files: vec![FileRename { old_uri, new_uri }],
 8850                                    })
 8851                                    .await
 8852                                    .into_response()
 8853                                    .context("will rename files")
 8854                                    .log_err()
 8855                                    .flatten()?;
 8856
 8857                                let transaction = LocalLspStore::deserialize_workspace_edit(
 8858                                    this.upgrade()?,
 8859                                    edit,
 8860                                    false,
 8861                                    language_server.clone(),
 8862                                    cx,
 8863                                )
 8864                                .await
 8865                                .ok()?;
 8866                                Some(transaction)
 8867                            }
 8868                        });
 8869                        tasks.push(apply_edit);
 8870                    }
 8871                }
 8872                Some(())
 8873            })
 8874            .ok()
 8875            .flatten();
 8876            let mut merged_transaction = ProjectTransaction::default();
 8877            for task in tasks {
 8878                // Await on tasks sequentially so that the order of application of edits is deterministic
 8879                // (at least with regards to the order of registration of language servers)
 8880                if let Some(transaction) = task.await {
 8881                    for (buffer, buffer_transaction) in transaction.0 {
 8882                        merged_transaction.0.insert(buffer, buffer_transaction);
 8883                    }
 8884                }
 8885            }
 8886            merged_transaction
 8887        })
 8888    }
 8889
 8890    fn lsp_notify_abs_paths_changed(
 8891        &mut self,
 8892        server_id: LanguageServerId,
 8893        changes: Vec<PathEvent>,
 8894    ) {
 8895        maybe!({
 8896            let server = self.language_server_for_id(server_id)?;
 8897            let changes = changes
 8898                .into_iter()
 8899                .filter_map(|event| {
 8900                    let typ = match event.kind? {
 8901                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 8902                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 8903                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 8904                    };
 8905                    Some(lsp::FileEvent {
 8906                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 8907                        typ,
 8908                    })
 8909                })
 8910                .collect::<Vec<_>>();
 8911            if !changes.is_empty() {
 8912                server
 8913                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 8914                        &lsp::DidChangeWatchedFilesParams { changes },
 8915                    )
 8916                    .ok();
 8917            }
 8918            Some(())
 8919        });
 8920    }
 8921
 8922    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 8923        self.as_local()?.language_server_for_id(id)
 8924    }
 8925
 8926    fn on_lsp_progress(
 8927        &mut self,
 8928        progress: lsp::ProgressParams,
 8929        language_server_id: LanguageServerId,
 8930        disk_based_diagnostics_progress_token: Option<String>,
 8931        cx: &mut Context<Self>,
 8932    ) {
 8933        let token = match progress.token {
 8934            lsp::NumberOrString::String(token) => token,
 8935            lsp::NumberOrString::Number(token) => {
 8936                log::info!("skipping numeric progress token {}", token);
 8937                return;
 8938            }
 8939        };
 8940
 8941        match progress.value {
 8942            lsp::ProgressParamsValue::WorkDone(progress) => {
 8943                self.handle_work_done_progress(
 8944                    progress,
 8945                    language_server_id,
 8946                    disk_based_diagnostics_progress_token,
 8947                    token,
 8948                    cx,
 8949                );
 8950            }
 8951            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 8952                if let Some(LanguageServerState::Running {
 8953                    workspace_refresh_task: Some(workspace_refresh_task),
 8954                    ..
 8955                }) = self
 8956                    .as_local_mut()
 8957                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 8958                {
 8959                    workspace_refresh_task.progress_tx.try_send(()).ok();
 8960                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 8961                }
 8962            }
 8963        }
 8964    }
 8965
 8966    fn handle_work_done_progress(
 8967        &mut self,
 8968        progress: lsp::WorkDoneProgress,
 8969        language_server_id: LanguageServerId,
 8970        disk_based_diagnostics_progress_token: Option<String>,
 8971        token: String,
 8972        cx: &mut Context<Self>,
 8973    ) {
 8974        let language_server_status =
 8975            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 8976                status
 8977            } else {
 8978                return;
 8979            };
 8980
 8981        if !language_server_status.progress_tokens.contains(&token) {
 8982            return;
 8983        }
 8984
 8985        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 8986            .as_ref()
 8987            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 8988
 8989        match progress {
 8990            lsp::WorkDoneProgress::Begin(report) => {
 8991                if is_disk_based_diagnostics_progress {
 8992                    self.disk_based_diagnostics_started(language_server_id, cx);
 8993                }
 8994                self.on_lsp_work_start(
 8995                    language_server_id,
 8996                    token.clone(),
 8997                    LanguageServerProgress {
 8998                        title: Some(report.title),
 8999                        is_disk_based_diagnostics_progress,
 9000                        is_cancellable: report.cancellable.unwrap_or(false),
 9001                        message: report.message.clone(),
 9002                        percentage: report.percentage.map(|p| p as usize),
 9003                        last_update_at: cx.background_executor().now(),
 9004                    },
 9005                    cx,
 9006                );
 9007            }
 9008            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9009                language_server_id,
 9010                token,
 9011                LanguageServerProgress {
 9012                    title: None,
 9013                    is_disk_based_diagnostics_progress,
 9014                    is_cancellable: report.cancellable.unwrap_or(false),
 9015                    message: report.message,
 9016                    percentage: report.percentage.map(|p| p as usize),
 9017                    last_update_at: cx.background_executor().now(),
 9018                },
 9019                cx,
 9020            ),
 9021            lsp::WorkDoneProgress::End(_) => {
 9022                language_server_status.progress_tokens.remove(&token);
 9023                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9024                if is_disk_based_diagnostics_progress {
 9025                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9026                }
 9027            }
 9028        }
 9029    }
 9030
 9031    fn on_lsp_work_start(
 9032        &mut self,
 9033        language_server_id: LanguageServerId,
 9034        token: String,
 9035        progress: LanguageServerProgress,
 9036        cx: &mut Context<Self>,
 9037    ) {
 9038        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9039            status.pending_work.insert(token.clone(), progress.clone());
 9040            cx.notify();
 9041        }
 9042        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9043            language_server_id,
 9044            name: self
 9045                .language_server_adapter_for_id(language_server_id)
 9046                .map(|adapter| adapter.name()),
 9047            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9048                token,
 9049                title: progress.title,
 9050                message: progress.message,
 9051                percentage: progress.percentage.map(|p| p as u32),
 9052                is_cancellable: Some(progress.is_cancellable),
 9053            }),
 9054        })
 9055    }
 9056
 9057    fn on_lsp_work_progress(
 9058        &mut self,
 9059        language_server_id: LanguageServerId,
 9060        token: String,
 9061        progress: LanguageServerProgress,
 9062        cx: &mut Context<Self>,
 9063    ) {
 9064        let mut did_update = false;
 9065        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9066            match status.pending_work.entry(token.clone()) {
 9067                btree_map::Entry::Vacant(entry) => {
 9068                    entry.insert(progress.clone());
 9069                    did_update = true;
 9070                }
 9071                btree_map::Entry::Occupied(mut entry) => {
 9072                    let entry = entry.get_mut();
 9073                    if (progress.last_update_at - entry.last_update_at)
 9074                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9075                    {
 9076                        entry.last_update_at = progress.last_update_at;
 9077                        if progress.message.is_some() {
 9078                            entry.message = progress.message.clone();
 9079                        }
 9080                        if progress.percentage.is_some() {
 9081                            entry.percentage = progress.percentage;
 9082                        }
 9083                        if progress.is_cancellable != entry.is_cancellable {
 9084                            entry.is_cancellable = progress.is_cancellable;
 9085                        }
 9086                        did_update = true;
 9087                    }
 9088                }
 9089            }
 9090        }
 9091
 9092        if did_update {
 9093            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9094                language_server_id,
 9095                name: self
 9096                    .language_server_adapter_for_id(language_server_id)
 9097                    .map(|adapter| adapter.name()),
 9098                message: proto::update_language_server::Variant::WorkProgress(
 9099                    proto::LspWorkProgress {
 9100                        token,
 9101                        message: progress.message,
 9102                        percentage: progress.percentage.map(|p| p as u32),
 9103                        is_cancellable: Some(progress.is_cancellable),
 9104                    },
 9105                ),
 9106            })
 9107        }
 9108    }
 9109
 9110    fn on_lsp_work_end(
 9111        &mut self,
 9112        language_server_id: LanguageServerId,
 9113        token: String,
 9114        cx: &mut Context<Self>,
 9115    ) {
 9116        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9117            if let Some(work) = status.pending_work.remove(&token)
 9118                && !work.is_disk_based_diagnostics_progress
 9119            {
 9120                cx.emit(LspStoreEvent::RefreshInlayHints);
 9121            }
 9122            cx.notify();
 9123        }
 9124
 9125        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9126            language_server_id,
 9127            name: self
 9128                .language_server_adapter_for_id(language_server_id)
 9129                .map(|adapter| adapter.name()),
 9130            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9131        })
 9132    }
 9133
 9134    pub async fn handle_resolve_completion_documentation(
 9135        this: Entity<Self>,
 9136        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9137        mut cx: AsyncApp,
 9138    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9139        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9140
 9141        let completion = this
 9142            .read_with(&cx, |this, cx| {
 9143                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9144                let server = this
 9145                    .language_server_for_id(id)
 9146                    .with_context(|| format!("No language server {id}"))?;
 9147
 9148                anyhow::Ok(cx.background_spawn(async move {
 9149                    let can_resolve = server
 9150                        .capabilities()
 9151                        .completion_provider
 9152                        .as_ref()
 9153                        .and_then(|options| options.resolve_provider)
 9154                        .unwrap_or(false);
 9155                    if can_resolve {
 9156                        server
 9157                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9158                            .await
 9159                            .into_response()
 9160                            .context("resolve completion item")
 9161                    } else {
 9162                        anyhow::Ok(lsp_completion)
 9163                    }
 9164                }))
 9165            })??
 9166            .await?;
 9167
 9168        let mut documentation_is_markdown = false;
 9169        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9170        let documentation = match completion.documentation {
 9171            Some(lsp::Documentation::String(text)) => text,
 9172
 9173            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9174                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9175                value
 9176            }
 9177
 9178            _ => String::new(),
 9179        };
 9180
 9181        // If we have a new buffer_id, that means we're talking to a new client
 9182        // and want to check for new text_edits in the completion too.
 9183        let mut old_replace_start = None;
 9184        let mut old_replace_end = None;
 9185        let mut old_insert_start = None;
 9186        let mut old_insert_end = None;
 9187        let mut new_text = String::default();
 9188        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9189            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9190                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9191                anyhow::Ok(buffer.read(cx).snapshot())
 9192            })??;
 9193
 9194            if let Some(text_edit) = completion.text_edit.as_ref() {
 9195                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9196
 9197                if let Some(mut edit) = edit {
 9198                    LineEnding::normalize(&mut edit.new_text);
 9199
 9200                    new_text = edit.new_text;
 9201                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9202                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9203                    if let Some(insert_range) = edit.insert_range {
 9204                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9205                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9206                    }
 9207                }
 9208            }
 9209        }
 9210
 9211        Ok(proto::ResolveCompletionDocumentationResponse {
 9212            documentation,
 9213            documentation_is_markdown,
 9214            old_replace_start,
 9215            old_replace_end,
 9216            new_text,
 9217            lsp_completion,
 9218            old_insert_start,
 9219            old_insert_end,
 9220        })
 9221    }
 9222
 9223    async fn handle_on_type_formatting(
 9224        this: Entity<Self>,
 9225        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9226        mut cx: AsyncApp,
 9227    ) -> Result<proto::OnTypeFormattingResponse> {
 9228        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9229            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9230            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9231            let position = envelope
 9232                .payload
 9233                .position
 9234                .and_then(deserialize_anchor)
 9235                .context("invalid position")?;
 9236            anyhow::Ok(this.apply_on_type_formatting(
 9237                buffer,
 9238                position,
 9239                envelope.payload.trigger.clone(),
 9240                cx,
 9241            ))
 9242        })??;
 9243
 9244        let transaction = on_type_formatting
 9245            .await?
 9246            .as_ref()
 9247            .map(language::proto::serialize_transaction);
 9248        Ok(proto::OnTypeFormattingResponse { transaction })
 9249    }
 9250
 9251    async fn handle_refresh_inlay_hints(
 9252        this: Entity<Self>,
 9253        _: TypedEnvelope<proto::RefreshInlayHints>,
 9254        mut cx: AsyncApp,
 9255    ) -> Result<proto::Ack> {
 9256        this.update(&mut cx, |_, cx| {
 9257            cx.emit(LspStoreEvent::RefreshInlayHints);
 9258        })?;
 9259        Ok(proto::Ack {})
 9260    }
 9261
 9262    async fn handle_pull_workspace_diagnostics(
 9263        lsp_store: Entity<Self>,
 9264        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9265        mut cx: AsyncApp,
 9266    ) -> Result<proto::Ack> {
 9267        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9268        lsp_store.update(&mut cx, |lsp_store, _| {
 9269            lsp_store.pull_workspace_diagnostics(server_id);
 9270        })?;
 9271        Ok(proto::Ack {})
 9272    }
 9273
 9274    async fn handle_inlay_hints(
 9275        this: Entity<Self>,
 9276        envelope: TypedEnvelope<proto::InlayHints>,
 9277        mut cx: AsyncApp,
 9278    ) -> Result<proto::InlayHintsResponse> {
 9279        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9280        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9281        let buffer = this.update(&mut cx, |this, cx| {
 9282            this.buffer_store.read(cx).get_existing(buffer_id)
 9283        })??;
 9284        buffer
 9285            .update(&mut cx, |buffer, _| {
 9286                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9287            })?
 9288            .await
 9289            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9290
 9291        let start = envelope
 9292            .payload
 9293            .start
 9294            .and_then(deserialize_anchor)
 9295            .context("missing range start")?;
 9296        let end = envelope
 9297            .payload
 9298            .end
 9299            .and_then(deserialize_anchor)
 9300            .context("missing range end")?;
 9301        let buffer_hints = this
 9302            .update(&mut cx, |lsp_store, cx| {
 9303                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9304            })?
 9305            .await
 9306            .context("inlay hints fetch")?;
 9307
 9308        this.update(&mut cx, |project, cx| {
 9309            InlayHints::response_to_proto(
 9310                buffer_hints,
 9311                project,
 9312                sender_id,
 9313                &buffer.read(cx).version(),
 9314                cx,
 9315            )
 9316        })
 9317    }
 9318
 9319    async fn handle_get_color_presentation(
 9320        lsp_store: Entity<Self>,
 9321        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9322        mut cx: AsyncApp,
 9323    ) -> Result<proto::GetColorPresentationResponse> {
 9324        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9325        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9326            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9327        })??;
 9328
 9329        let color = envelope
 9330            .payload
 9331            .color
 9332            .context("invalid color resolve request")?;
 9333        let start = color
 9334            .lsp_range_start
 9335            .context("invalid color resolve request")?;
 9336        let end = color
 9337            .lsp_range_end
 9338            .context("invalid color resolve request")?;
 9339
 9340        let color = DocumentColor {
 9341            lsp_range: lsp::Range {
 9342                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9343                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9344            },
 9345            color: lsp::Color {
 9346                red: color.red,
 9347                green: color.green,
 9348                blue: color.blue,
 9349                alpha: color.alpha,
 9350            },
 9351            resolved: false,
 9352            color_presentations: Vec::new(),
 9353        };
 9354        let resolved_color = lsp_store
 9355            .update(&mut cx, |lsp_store, cx| {
 9356                lsp_store.resolve_color_presentation(
 9357                    color,
 9358                    buffer.clone(),
 9359                    LanguageServerId(envelope.payload.server_id as usize),
 9360                    cx,
 9361                )
 9362            })?
 9363            .await
 9364            .context("resolving color presentation")?;
 9365
 9366        Ok(proto::GetColorPresentationResponse {
 9367            presentations: resolved_color
 9368                .color_presentations
 9369                .into_iter()
 9370                .map(|presentation| proto::ColorPresentation {
 9371                    label: presentation.label.to_string(),
 9372                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9373                    additional_text_edits: presentation
 9374                        .additional_text_edits
 9375                        .into_iter()
 9376                        .map(serialize_lsp_edit)
 9377                        .collect(),
 9378                })
 9379                .collect(),
 9380        })
 9381    }
 9382
 9383    async fn handle_resolve_inlay_hint(
 9384        this: Entity<Self>,
 9385        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9386        mut cx: AsyncApp,
 9387    ) -> Result<proto::ResolveInlayHintResponse> {
 9388        let proto_hint = envelope
 9389            .payload
 9390            .hint
 9391            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9392        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9393            .context("resolved proto inlay hint conversion")?;
 9394        let buffer = this.update(&mut cx, |this, cx| {
 9395            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9396            this.buffer_store.read(cx).get_existing(buffer_id)
 9397        })??;
 9398        let response_hint = this
 9399            .update(&mut cx, |this, cx| {
 9400                this.resolve_inlay_hint(
 9401                    hint,
 9402                    buffer,
 9403                    LanguageServerId(envelope.payload.language_server_id as usize),
 9404                    cx,
 9405                )
 9406            })?
 9407            .await
 9408            .context("inlay hints fetch")?;
 9409        Ok(proto::ResolveInlayHintResponse {
 9410            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9411        })
 9412    }
 9413
 9414    async fn handle_refresh_code_lens(
 9415        this: Entity<Self>,
 9416        _: TypedEnvelope<proto::RefreshCodeLens>,
 9417        mut cx: AsyncApp,
 9418    ) -> Result<proto::Ack> {
 9419        this.update(&mut cx, |_, cx| {
 9420            cx.emit(LspStoreEvent::RefreshCodeLens);
 9421        })?;
 9422        Ok(proto::Ack {})
 9423    }
 9424
 9425    async fn handle_open_buffer_for_symbol(
 9426        this: Entity<Self>,
 9427        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9428        mut cx: AsyncApp,
 9429    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9430        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9431        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9432        let symbol = Self::deserialize_symbol(symbol)?;
 9433        let symbol = this.read_with(&cx, |this, _| {
 9434            let signature = this.symbol_signature(&symbol.path);
 9435            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9436            Ok(symbol)
 9437        })??;
 9438        let buffer = this
 9439            .update(&mut cx, |this, cx| {
 9440                this.open_buffer_for_symbol(
 9441                    &Symbol {
 9442                        language_server_name: symbol.language_server_name,
 9443                        source_worktree_id: symbol.source_worktree_id,
 9444                        source_language_server_id: symbol.source_language_server_id,
 9445                        path: symbol.path,
 9446                        name: symbol.name,
 9447                        kind: symbol.kind,
 9448                        range: symbol.range,
 9449                        signature: symbol.signature,
 9450                        label: CodeLabel {
 9451                            text: Default::default(),
 9452                            runs: Default::default(),
 9453                            filter_range: Default::default(),
 9454                        },
 9455                    },
 9456                    cx,
 9457                )
 9458            })?
 9459            .await?;
 9460
 9461        this.update(&mut cx, |this, cx| {
 9462            let is_private = buffer
 9463                .read(cx)
 9464                .file()
 9465                .map(|f| f.is_private())
 9466                .unwrap_or_default();
 9467            if is_private {
 9468                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9469            } else {
 9470                this.buffer_store
 9471                    .update(cx, |buffer_store, cx| {
 9472                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9473                    })
 9474                    .detach_and_log_err(cx);
 9475                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9476                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9477            }
 9478        })?
 9479    }
 9480
 9481    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9482        let mut hasher = Sha256::new();
 9483        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9484        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9485        hasher.update(self.nonce.to_be_bytes());
 9486        hasher.finalize().as_slice().try_into().unwrap()
 9487    }
 9488
 9489    pub async fn handle_get_project_symbols(
 9490        this: Entity<Self>,
 9491        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9492        mut cx: AsyncApp,
 9493    ) -> Result<proto::GetProjectSymbolsResponse> {
 9494        let symbols = this
 9495            .update(&mut cx, |this, cx| {
 9496                this.symbols(&envelope.payload.query, cx)
 9497            })?
 9498            .await?;
 9499
 9500        Ok(proto::GetProjectSymbolsResponse {
 9501            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9502        })
 9503    }
 9504
 9505    pub async fn handle_restart_language_servers(
 9506        this: Entity<Self>,
 9507        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9508        mut cx: AsyncApp,
 9509    ) -> Result<proto::Ack> {
 9510        this.update(&mut cx, |lsp_store, cx| {
 9511            let buffers =
 9512                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9513            lsp_store.restart_language_servers_for_buffers(
 9514                buffers,
 9515                envelope
 9516                    .payload
 9517                    .only_servers
 9518                    .into_iter()
 9519                    .filter_map(|selector| {
 9520                        Some(match selector.selector? {
 9521                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9522                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9523                            }
 9524                            proto::language_server_selector::Selector::Name(name) => {
 9525                                LanguageServerSelector::Name(LanguageServerName(
 9526                                    SharedString::from(name),
 9527                                ))
 9528                            }
 9529                        })
 9530                    })
 9531                    .collect(),
 9532                cx,
 9533            );
 9534        })?;
 9535
 9536        Ok(proto::Ack {})
 9537    }
 9538
 9539    pub async fn handle_stop_language_servers(
 9540        lsp_store: Entity<Self>,
 9541        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9542        mut cx: AsyncApp,
 9543    ) -> Result<proto::Ack> {
 9544        lsp_store.update(&mut cx, |lsp_store, cx| {
 9545            if envelope.payload.all
 9546                && envelope.payload.also_servers.is_empty()
 9547                && envelope.payload.buffer_ids.is_empty()
 9548            {
 9549                lsp_store.stop_all_language_servers(cx);
 9550            } else {
 9551                let buffers =
 9552                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9553                lsp_store
 9554                    .stop_language_servers_for_buffers(
 9555                        buffers,
 9556                        envelope
 9557                            .payload
 9558                            .also_servers
 9559                            .into_iter()
 9560                            .filter_map(|selector| {
 9561                                Some(match selector.selector? {
 9562                                    proto::language_server_selector::Selector::ServerId(
 9563                                        server_id,
 9564                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9565                                        server_id,
 9566                                    )),
 9567                                    proto::language_server_selector::Selector::Name(name) => {
 9568                                        LanguageServerSelector::Name(LanguageServerName(
 9569                                            SharedString::from(name),
 9570                                        ))
 9571                                    }
 9572                                })
 9573                            })
 9574                            .collect(),
 9575                        cx,
 9576                    )
 9577                    .detach_and_log_err(cx);
 9578            }
 9579        })?;
 9580
 9581        Ok(proto::Ack {})
 9582    }
 9583
 9584    pub async fn handle_cancel_language_server_work(
 9585        this: Entity<Self>,
 9586        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9587        mut cx: AsyncApp,
 9588    ) -> Result<proto::Ack> {
 9589        this.update(&mut cx, |this, cx| {
 9590            if let Some(work) = envelope.payload.work {
 9591                match work {
 9592                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9593                        let buffers =
 9594                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9595                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9596                    }
 9597                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9598                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9599                        this.cancel_language_server_work(server_id, work.token, cx);
 9600                    }
 9601                }
 9602            }
 9603        })?;
 9604
 9605        Ok(proto::Ack {})
 9606    }
 9607
 9608    fn buffer_ids_to_buffers(
 9609        &mut self,
 9610        buffer_ids: impl Iterator<Item = u64>,
 9611        cx: &mut Context<Self>,
 9612    ) -> Vec<Entity<Buffer>> {
 9613        buffer_ids
 9614            .into_iter()
 9615            .flat_map(|buffer_id| {
 9616                self.buffer_store
 9617                    .read(cx)
 9618                    .get(BufferId::new(buffer_id).log_err()?)
 9619            })
 9620            .collect::<Vec<_>>()
 9621    }
 9622
 9623    async fn handle_apply_additional_edits_for_completion(
 9624        this: Entity<Self>,
 9625        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9626        mut cx: AsyncApp,
 9627    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9628        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9629            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9630            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9631            let completion = Self::deserialize_completion(
 9632                envelope.payload.completion.context("invalid completion")?,
 9633            )?;
 9634            anyhow::Ok((buffer, completion))
 9635        })??;
 9636
 9637        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9638            this.apply_additional_edits_for_completion(
 9639                buffer,
 9640                Rc::new(RefCell::new(Box::new([Completion {
 9641                    replace_range: completion.replace_range,
 9642                    new_text: completion.new_text,
 9643                    source: completion.source,
 9644                    documentation: None,
 9645                    label: CodeLabel {
 9646                        text: Default::default(),
 9647                        runs: Default::default(),
 9648                        filter_range: Default::default(),
 9649                    },
 9650                    insert_text_mode: None,
 9651                    icon_path: None,
 9652                    confirm: None,
 9653                }]))),
 9654                0,
 9655                false,
 9656                cx,
 9657            )
 9658        })?;
 9659
 9660        Ok(proto::ApplyCompletionAdditionalEditsResponse {
 9661            transaction: apply_additional_edits
 9662                .await?
 9663                .as_ref()
 9664                .map(language::proto::serialize_transaction),
 9665        })
 9666    }
 9667
 9668    pub fn last_formatting_failure(&self) -> Option<&str> {
 9669        self.last_formatting_failure.as_deref()
 9670    }
 9671
 9672    pub fn reset_last_formatting_failure(&mut self) {
 9673        self.last_formatting_failure = None;
 9674    }
 9675
 9676    pub fn environment_for_buffer(
 9677        &self,
 9678        buffer: &Entity<Buffer>,
 9679        cx: &mut Context<Self>,
 9680    ) -> Shared<Task<Option<HashMap<String, String>>>> {
 9681        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
 9682            environment.update(cx, |env, cx| {
 9683                env.get_buffer_environment(buffer, &self.worktree_store, cx)
 9684            })
 9685        } else {
 9686            Task::ready(None).shared()
 9687        }
 9688    }
 9689
 9690    pub fn format(
 9691        &mut self,
 9692        buffers: HashSet<Entity<Buffer>>,
 9693        target: LspFormatTarget,
 9694        push_to_history: bool,
 9695        trigger: FormatTrigger,
 9696        cx: &mut Context<Self>,
 9697    ) -> Task<anyhow::Result<ProjectTransaction>> {
 9698        let logger = zlog::scoped!("format");
 9699        if self.as_local().is_some() {
 9700            zlog::trace!(logger => "Formatting locally");
 9701            let logger = zlog::scoped!(logger => "local");
 9702            let buffers = buffers
 9703                .into_iter()
 9704                .map(|buffer_handle| {
 9705                    let buffer = buffer_handle.read(cx);
 9706                    let buffer_abs_path = File::from_dyn(buffer.file())
 9707                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
 9708
 9709                    (buffer_handle, buffer_abs_path, buffer.remote_id())
 9710                })
 9711                .collect::<Vec<_>>();
 9712
 9713            cx.spawn(async move |lsp_store, cx| {
 9714                let mut formattable_buffers = Vec::with_capacity(buffers.len());
 9715
 9716                for (handle, abs_path, id) in buffers {
 9717                    let env = lsp_store
 9718                        .update(cx, |lsp_store, cx| {
 9719                            lsp_store.environment_for_buffer(&handle, cx)
 9720                        })?
 9721                        .await;
 9722
 9723                    let ranges = match &target {
 9724                        LspFormatTarget::Buffers => None,
 9725                        LspFormatTarget::Ranges(ranges) => {
 9726                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
 9727                        }
 9728                    };
 9729
 9730                    formattable_buffers.push(FormattableBuffer {
 9731                        handle,
 9732                        abs_path,
 9733                        env,
 9734                        ranges,
 9735                    });
 9736                }
 9737                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
 9738
 9739                let format_timer = zlog::time!(logger => "Formatting buffers");
 9740                let result = LocalLspStore::format_locally(
 9741                    lsp_store.clone(),
 9742                    formattable_buffers,
 9743                    push_to_history,
 9744                    trigger,
 9745                    logger,
 9746                    cx,
 9747                )
 9748                .await;
 9749                format_timer.end();
 9750
 9751                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
 9752
 9753                lsp_store.update(cx, |lsp_store, _| {
 9754                    lsp_store.update_last_formatting_failure(&result);
 9755                })?;
 9756
 9757                result
 9758            })
 9759        } else if let Some((client, project_id)) = self.upstream_client() {
 9760            zlog::trace!(logger => "Formatting remotely");
 9761            let logger = zlog::scoped!(logger => "remote");
 9762            // Don't support formatting ranges via remote
 9763            match target {
 9764                LspFormatTarget::Buffers => {}
 9765                LspFormatTarget::Ranges(_) => {
 9766                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
 9767                    return Task::ready(Ok(ProjectTransaction::default()));
 9768                }
 9769            }
 9770
 9771            let buffer_store = self.buffer_store();
 9772            cx.spawn(async move |lsp_store, cx| {
 9773                zlog::trace!(logger => "Sending remote format request");
 9774                let request_timer = zlog::time!(logger => "remote format request");
 9775                let result = client
 9776                    .request(proto::FormatBuffers {
 9777                        project_id,
 9778                        trigger: trigger as i32,
 9779                        buffer_ids: buffers
 9780                            .iter()
 9781                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
 9782                            .collect::<Result<_>>()?,
 9783                    })
 9784                    .await
 9785                    .and_then(|result| result.transaction.context("missing transaction"));
 9786                request_timer.end();
 9787
 9788                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
 9789
 9790                lsp_store.update(cx, |lsp_store, _| {
 9791                    lsp_store.update_last_formatting_failure(&result);
 9792                })?;
 9793
 9794                let transaction_response = result?;
 9795                let _timer = zlog::time!(logger => "deserializing project transaction");
 9796                buffer_store
 9797                    .update(cx, |buffer_store, cx| {
 9798                        buffer_store.deserialize_project_transaction(
 9799                            transaction_response,
 9800                            push_to_history,
 9801                            cx,
 9802                        )
 9803                    })?
 9804                    .await
 9805            })
 9806        } else {
 9807            zlog::trace!(logger => "Not formatting");
 9808            Task::ready(Ok(ProjectTransaction::default()))
 9809        }
 9810    }
 9811
 9812    async fn handle_format_buffers(
 9813        this: Entity<Self>,
 9814        envelope: TypedEnvelope<proto::FormatBuffers>,
 9815        mut cx: AsyncApp,
 9816    ) -> Result<proto::FormatBuffersResponse> {
 9817        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9818        let format = this.update(&mut cx, |this, cx| {
 9819            let mut buffers = HashSet::default();
 9820            for buffer_id in &envelope.payload.buffer_ids {
 9821                let buffer_id = BufferId::new(*buffer_id)?;
 9822                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9823            }
 9824            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
 9825            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
 9826        })??;
 9827
 9828        let project_transaction = format.await?;
 9829        let project_transaction = this.update(&mut cx, |this, cx| {
 9830            this.buffer_store.update(cx, |buffer_store, cx| {
 9831                buffer_store.serialize_project_transaction_for_peer(
 9832                    project_transaction,
 9833                    sender_id,
 9834                    cx,
 9835                )
 9836            })
 9837        })?;
 9838        Ok(proto::FormatBuffersResponse {
 9839            transaction: Some(project_transaction),
 9840        })
 9841    }
 9842
 9843    async fn handle_apply_code_action_kind(
 9844        this: Entity<Self>,
 9845        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
 9846        mut cx: AsyncApp,
 9847    ) -> Result<proto::ApplyCodeActionKindResponse> {
 9848        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9849        let format = this.update(&mut cx, |this, cx| {
 9850            let mut buffers = HashSet::default();
 9851            for buffer_id in &envelope.payload.buffer_ids {
 9852                let buffer_id = BufferId::new(*buffer_id)?;
 9853                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9854            }
 9855            let kind = match envelope.payload.kind.as_str() {
 9856                "" => CodeActionKind::EMPTY,
 9857                "quickfix" => CodeActionKind::QUICKFIX,
 9858                "refactor" => CodeActionKind::REFACTOR,
 9859                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
 9860                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
 9861                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
 9862                "source" => CodeActionKind::SOURCE,
 9863                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
 9864                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
 9865                _ => anyhow::bail!(
 9866                    "Invalid code action kind {}",
 9867                    envelope.payload.kind.as_str()
 9868                ),
 9869            };
 9870            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
 9871        })??;
 9872
 9873        let project_transaction = format.await?;
 9874        let project_transaction = this.update(&mut cx, |this, cx| {
 9875            this.buffer_store.update(cx, |buffer_store, cx| {
 9876                buffer_store.serialize_project_transaction_for_peer(
 9877                    project_transaction,
 9878                    sender_id,
 9879                    cx,
 9880                )
 9881            })
 9882        })?;
 9883        Ok(proto::ApplyCodeActionKindResponse {
 9884            transaction: Some(project_transaction),
 9885        })
 9886    }
 9887
 9888    async fn shutdown_language_server(
 9889        server_state: Option<LanguageServerState>,
 9890        name: LanguageServerName,
 9891        cx: &mut AsyncApp,
 9892    ) {
 9893        let server = match server_state {
 9894            Some(LanguageServerState::Starting { startup, .. }) => {
 9895                let mut timer = cx
 9896                    .background_executor()
 9897                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
 9898                    .fuse();
 9899
 9900                select! {
 9901                    server = startup.fuse() => server,
 9902                    () = timer => {
 9903                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
 9904                        None
 9905                    },
 9906                }
 9907            }
 9908
 9909            Some(LanguageServerState::Running { server, .. }) => Some(server),
 9910
 9911            None => None,
 9912        };
 9913
 9914        if let Some(server) = server
 9915            && let Some(shutdown) = server.shutdown()
 9916        {
 9917            shutdown.await;
 9918        }
 9919    }
 9920
 9921    // Returns a list of all of the worktrees which no longer have a language server and the root path
 9922    // for the stopped server
 9923    fn stop_local_language_server(
 9924        &mut self,
 9925        server_id: LanguageServerId,
 9926        cx: &mut Context<Self>,
 9927    ) -> Task<()> {
 9928        let local = match &mut self.mode {
 9929            LspStoreMode::Local(local) => local,
 9930            _ => {
 9931                return Task::ready(());
 9932            }
 9933        };
 9934
 9935        // Remove this server ID from all entries in the given worktree.
 9936        local
 9937            .language_server_ids
 9938            .retain(|_, state| state.id != server_id);
 9939        self.buffer_store.update(cx, |buffer_store, cx| {
 9940            for buffer in buffer_store.buffers() {
 9941                buffer.update(cx, |buffer, cx| {
 9942                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 9943                    buffer.set_completion_triggers(server_id, Default::default(), cx);
 9944                });
 9945            }
 9946        });
 9947
 9948        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
 9949            summaries.retain(|path, summaries_by_server_id| {
 9950                if summaries_by_server_id.remove(&server_id).is_some() {
 9951                    if let Some((client, project_id)) = self.downstream_client.clone() {
 9952                        client
 9953                            .send(proto::UpdateDiagnosticSummary {
 9954                                project_id,
 9955                                worktree_id: worktree_id.to_proto(),
 9956                                summary: Some(proto::DiagnosticSummary {
 9957                                    path: path.as_ref().to_proto(),
 9958                                    language_server_id: server_id.0 as u64,
 9959                                    error_count: 0,
 9960                                    warning_count: 0,
 9961                                }),
 9962                                more_summaries: Vec::new(),
 9963                            })
 9964                            .log_err();
 9965                    }
 9966                    !summaries_by_server_id.is_empty()
 9967                } else {
 9968                    true
 9969                }
 9970            });
 9971        }
 9972
 9973        let local = self.as_local_mut().unwrap();
 9974        for diagnostics in local.diagnostics.values_mut() {
 9975            diagnostics.retain(|_, diagnostics_by_server_id| {
 9976                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 9977                    diagnostics_by_server_id.remove(ix);
 9978                    !diagnostics_by_server_id.is_empty()
 9979                } else {
 9980                    true
 9981                }
 9982            });
 9983        }
 9984        local.language_server_watched_paths.remove(&server_id);
 9985
 9986        let server_state = local.language_servers.remove(&server_id);
 9987        self.cleanup_lsp_data(server_id);
 9988        let name = self
 9989            .language_server_statuses
 9990            .remove(&server_id)
 9991            .map(|status| status.name)
 9992            .or_else(|| {
 9993                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
 9994                    Some(adapter.name())
 9995                } else {
 9996                    None
 9997                }
 9998            });
 9999
10000        if let Some(name) = name {
10001            log::info!("stopping language server {name}");
10002            self.languages
10003                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10004            cx.notify();
10005
10006            return cx.spawn(async move |lsp_store, cx| {
10007                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10008                lsp_store
10009                    .update(cx, |lsp_store, cx| {
10010                        lsp_store
10011                            .languages
10012                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10013                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10014                        cx.notify();
10015                    })
10016                    .ok();
10017            });
10018        }
10019
10020        if server_state.is_some() {
10021            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10022        }
10023        Task::ready(())
10024    }
10025
10026    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10027        if let Some((client, project_id)) = self.upstream_client() {
10028            let request = client.request(proto::StopLanguageServers {
10029                project_id,
10030                buffer_ids: Vec::new(),
10031                also_servers: Vec::new(),
10032                all: true,
10033            });
10034            cx.background_spawn(request).detach_and_log_err(cx);
10035        } else {
10036            let Some(local) = self.as_local_mut() else {
10037                return;
10038            };
10039            let language_servers_to_stop = local
10040                .language_server_ids
10041                .values()
10042                .map(|state| state.id)
10043                .collect();
10044            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10045            let tasks = language_servers_to_stop
10046                .into_iter()
10047                .map(|server| self.stop_local_language_server(server, cx))
10048                .collect::<Vec<_>>();
10049            cx.background_spawn(async move {
10050                futures::future::join_all(tasks).await;
10051            })
10052            .detach();
10053        }
10054    }
10055
10056    pub fn restart_language_servers_for_buffers(
10057        &mut self,
10058        buffers: Vec<Entity<Buffer>>,
10059        only_restart_servers: HashSet<LanguageServerSelector>,
10060        cx: &mut Context<Self>,
10061    ) {
10062        if let Some((client, project_id)) = self.upstream_client() {
10063            let request = client.request(proto::RestartLanguageServers {
10064                project_id,
10065                buffer_ids: buffers
10066                    .into_iter()
10067                    .map(|b| b.read(cx).remote_id().to_proto())
10068                    .collect(),
10069                only_servers: only_restart_servers
10070                    .into_iter()
10071                    .map(|selector| {
10072                        let selector = match selector {
10073                            LanguageServerSelector::Id(language_server_id) => {
10074                                proto::language_server_selector::Selector::ServerId(
10075                                    language_server_id.to_proto(),
10076                                )
10077                            }
10078                            LanguageServerSelector::Name(language_server_name) => {
10079                                proto::language_server_selector::Selector::Name(
10080                                    language_server_name.to_string(),
10081                                )
10082                            }
10083                        };
10084                        proto::LanguageServerSelector {
10085                            selector: Some(selector),
10086                        }
10087                    })
10088                    .collect(),
10089                all: false,
10090            });
10091            cx.background_spawn(request).detach_and_log_err(cx);
10092        } else {
10093            let stop_task = if only_restart_servers.is_empty() {
10094                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10095            } else {
10096                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10097            };
10098            cx.spawn(async move |lsp_store, cx| {
10099                stop_task.await;
10100                lsp_store
10101                    .update(cx, |lsp_store, cx| {
10102                        for buffer in buffers {
10103                            lsp_store.register_buffer_with_language_servers(
10104                                &buffer,
10105                                only_restart_servers.clone(),
10106                                true,
10107                                cx,
10108                            );
10109                        }
10110                    })
10111                    .ok()
10112            })
10113            .detach();
10114        }
10115    }
10116
10117    pub fn stop_language_servers_for_buffers(
10118        &mut self,
10119        buffers: Vec<Entity<Buffer>>,
10120        also_stop_servers: HashSet<LanguageServerSelector>,
10121        cx: &mut Context<Self>,
10122    ) -> Task<Result<()>> {
10123        if let Some((client, project_id)) = self.upstream_client() {
10124            let request = client.request(proto::StopLanguageServers {
10125                project_id,
10126                buffer_ids: buffers
10127                    .into_iter()
10128                    .map(|b| b.read(cx).remote_id().to_proto())
10129                    .collect(),
10130                also_servers: also_stop_servers
10131                    .into_iter()
10132                    .map(|selector| {
10133                        let selector = match selector {
10134                            LanguageServerSelector::Id(language_server_id) => {
10135                                proto::language_server_selector::Selector::ServerId(
10136                                    language_server_id.to_proto(),
10137                                )
10138                            }
10139                            LanguageServerSelector::Name(language_server_name) => {
10140                                proto::language_server_selector::Selector::Name(
10141                                    language_server_name.to_string(),
10142                                )
10143                            }
10144                        };
10145                        proto::LanguageServerSelector {
10146                            selector: Some(selector),
10147                        }
10148                    })
10149                    .collect(),
10150                all: false,
10151            });
10152            cx.background_spawn(async move {
10153                let _ = request.await?;
10154                Ok(())
10155            })
10156        } else {
10157            let task =
10158                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10159            cx.background_spawn(async move {
10160                task.await;
10161                Ok(())
10162            })
10163        }
10164    }
10165
10166    fn stop_local_language_servers_for_buffers(
10167        &mut self,
10168        buffers: &[Entity<Buffer>],
10169        also_stop_servers: HashSet<LanguageServerSelector>,
10170        cx: &mut Context<Self>,
10171    ) -> Task<()> {
10172        let Some(local) = self.as_local_mut() else {
10173            return Task::ready(());
10174        };
10175        let mut language_server_names_to_stop = BTreeSet::default();
10176        let mut language_servers_to_stop = also_stop_servers
10177            .into_iter()
10178            .flat_map(|selector| match selector {
10179                LanguageServerSelector::Id(id) => Some(id),
10180                LanguageServerSelector::Name(name) => {
10181                    language_server_names_to_stop.insert(name);
10182                    None
10183                }
10184            })
10185            .collect::<BTreeSet<_>>();
10186
10187        let mut covered_worktrees = HashSet::default();
10188        for buffer in buffers {
10189            buffer.update(cx, |buffer, cx| {
10190                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10191                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10192                    && covered_worktrees.insert(worktree_id)
10193                {
10194                    language_server_names_to_stop.retain(|name| {
10195                        let old_ids_count = language_servers_to_stop.len();
10196                        let all_language_servers_with_this_name = local
10197                            .language_server_ids
10198                            .iter()
10199                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10200                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10201                        old_ids_count == language_servers_to_stop.len()
10202                    });
10203                }
10204            });
10205        }
10206        for name in language_server_names_to_stop {
10207            language_servers_to_stop.extend(
10208                local
10209                    .language_server_ids
10210                    .iter()
10211                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10212            );
10213        }
10214
10215        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10216        let tasks = language_servers_to_stop
10217            .into_iter()
10218            .map(|server| self.stop_local_language_server(server, cx))
10219            .collect::<Vec<_>>();
10220
10221        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10222    }
10223
10224    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10225        let (worktree, relative_path) =
10226            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10227
10228        let project_path = ProjectPath {
10229            worktree_id: worktree.read(cx).id(),
10230            path: relative_path.into(),
10231        };
10232
10233        Some(
10234            self.buffer_store()
10235                .read(cx)
10236                .get_by_path(&project_path)?
10237                .read(cx),
10238        )
10239    }
10240
10241    #[cfg(any(test, feature = "test-support"))]
10242    pub fn update_diagnostics(
10243        &mut self,
10244        server_id: LanguageServerId,
10245        diagnostics: lsp::PublishDiagnosticsParams,
10246        result_id: Option<String>,
10247        source_kind: DiagnosticSourceKind,
10248        disk_based_sources: &[String],
10249        cx: &mut Context<Self>,
10250    ) -> Result<()> {
10251        self.merge_lsp_diagnostics(
10252            source_kind,
10253            vec![DocumentDiagnosticsUpdate {
10254                diagnostics,
10255                result_id,
10256                server_id,
10257                disk_based_sources: Cow::Borrowed(disk_based_sources),
10258            }],
10259            |_, _, _| false,
10260            cx,
10261        )
10262    }
10263
10264    pub fn merge_lsp_diagnostics(
10265        &mut self,
10266        source_kind: DiagnosticSourceKind,
10267        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10268        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10269        cx: &mut Context<Self>,
10270    ) -> Result<()> {
10271        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10272        let updates = lsp_diagnostics
10273            .into_iter()
10274            .filter_map(|update| {
10275                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10276                Some(DocumentDiagnosticsUpdate {
10277                    diagnostics: self.lsp_to_document_diagnostics(
10278                        abs_path,
10279                        source_kind,
10280                        update.server_id,
10281                        update.diagnostics,
10282                        &update.disk_based_sources,
10283                    ),
10284                    result_id: update.result_id,
10285                    server_id: update.server_id,
10286                    disk_based_sources: update.disk_based_sources,
10287                })
10288            })
10289            .collect();
10290        self.merge_diagnostic_entries(updates, merge, cx)?;
10291        Ok(())
10292    }
10293
10294    fn lsp_to_document_diagnostics(
10295        &mut self,
10296        document_abs_path: PathBuf,
10297        source_kind: DiagnosticSourceKind,
10298        server_id: LanguageServerId,
10299        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10300        disk_based_sources: &[String],
10301    ) -> DocumentDiagnostics {
10302        let mut diagnostics = Vec::default();
10303        let mut primary_diagnostic_group_ids = HashMap::default();
10304        let mut sources_by_group_id = HashMap::default();
10305        let mut supporting_diagnostics = HashMap::default();
10306
10307        let adapter = self.language_server_adapter_for_id(server_id);
10308
10309        // Ensure that primary diagnostics are always the most severe
10310        lsp_diagnostics
10311            .diagnostics
10312            .sort_by_key(|item| item.severity);
10313
10314        for diagnostic in &lsp_diagnostics.diagnostics {
10315            let source = diagnostic.source.as_ref();
10316            let range = range_from_lsp(diagnostic.range);
10317            let is_supporting = diagnostic
10318                .related_information
10319                .as_ref()
10320                .is_some_and(|infos| {
10321                    infos.iter().any(|info| {
10322                        primary_diagnostic_group_ids.contains_key(&(
10323                            source,
10324                            diagnostic.code.clone(),
10325                            range_from_lsp(info.location.range),
10326                        ))
10327                    })
10328                });
10329
10330            let is_unnecessary = diagnostic
10331                .tags
10332                .as_ref()
10333                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10334
10335            let underline = self
10336                .language_server_adapter_for_id(server_id)
10337                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10338
10339            if is_supporting {
10340                supporting_diagnostics.insert(
10341                    (source, diagnostic.code.clone(), range),
10342                    (diagnostic.severity, is_unnecessary),
10343                );
10344            } else {
10345                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10346                let is_disk_based =
10347                    source.is_some_and(|source| disk_based_sources.contains(source));
10348
10349                sources_by_group_id.insert(group_id, source);
10350                primary_diagnostic_group_ids
10351                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10352
10353                diagnostics.push(DiagnosticEntry {
10354                    range,
10355                    diagnostic: Diagnostic {
10356                        source: diagnostic.source.clone(),
10357                        source_kind,
10358                        code: diagnostic.code.clone(),
10359                        code_description: diagnostic
10360                            .code_description
10361                            .as_ref()
10362                            .and_then(|d| d.href.clone()),
10363                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10364                        markdown: adapter.as_ref().and_then(|adapter| {
10365                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10366                        }),
10367                        message: diagnostic.message.trim().to_string(),
10368                        group_id,
10369                        is_primary: true,
10370                        is_disk_based,
10371                        is_unnecessary,
10372                        underline,
10373                        data: diagnostic.data.clone(),
10374                    },
10375                });
10376                if let Some(infos) = &diagnostic.related_information {
10377                    for info in infos {
10378                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10379                            let range = range_from_lsp(info.location.range);
10380                            diagnostics.push(DiagnosticEntry {
10381                                range,
10382                                diagnostic: Diagnostic {
10383                                    source: diagnostic.source.clone(),
10384                                    source_kind,
10385                                    code: diagnostic.code.clone(),
10386                                    code_description: diagnostic
10387                                        .code_description
10388                                        .as_ref()
10389                                        .and_then(|d| d.href.clone()),
10390                                    severity: DiagnosticSeverity::INFORMATION,
10391                                    markdown: adapter.as_ref().and_then(|adapter| {
10392                                        adapter.diagnostic_message_to_markdown(&info.message)
10393                                    }),
10394                                    message: info.message.trim().to_string(),
10395                                    group_id,
10396                                    is_primary: false,
10397                                    is_disk_based,
10398                                    is_unnecessary: false,
10399                                    underline,
10400                                    data: diagnostic.data.clone(),
10401                                },
10402                            });
10403                        }
10404                    }
10405                }
10406            }
10407        }
10408
10409        for entry in &mut diagnostics {
10410            let diagnostic = &mut entry.diagnostic;
10411            if !diagnostic.is_primary {
10412                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10413                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10414                    source,
10415                    diagnostic.code.clone(),
10416                    entry.range.clone(),
10417                )) {
10418                    if let Some(severity) = severity {
10419                        diagnostic.severity = severity;
10420                    }
10421                    diagnostic.is_unnecessary = is_unnecessary;
10422                }
10423            }
10424        }
10425
10426        DocumentDiagnostics {
10427            diagnostics,
10428            document_abs_path,
10429            version: lsp_diagnostics.version,
10430        }
10431    }
10432
10433    fn insert_newly_running_language_server(
10434        &mut self,
10435        adapter: Arc<CachedLspAdapter>,
10436        language_server: Arc<LanguageServer>,
10437        server_id: LanguageServerId,
10438        key: LanguageServerSeed,
10439        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10440        cx: &mut Context<Self>,
10441    ) {
10442        let Some(local) = self.as_local_mut() else {
10443            return;
10444        };
10445        // If the language server for this key doesn't match the server id, don't store the
10446        // server. Which will cause it to be dropped, killing the process
10447        if local
10448            .language_server_ids
10449            .get(&key)
10450            .map(|state| state.id != server_id)
10451            .unwrap_or(false)
10452        {
10453            return;
10454        }
10455
10456        // Update language_servers collection with Running variant of LanguageServerState
10457        // indicating that the server is up and running and ready
10458        let workspace_folders = workspace_folders.lock().clone();
10459        language_server.set_workspace_folders(workspace_folders);
10460
10461        local.language_servers.insert(
10462            server_id,
10463            LanguageServerState::Running {
10464                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10465                    language_server.clone(),
10466                    cx,
10467                ),
10468                adapter: adapter.clone(),
10469                server: language_server.clone(),
10470                simulate_disk_based_diagnostics_completion: None,
10471            },
10472        );
10473        local
10474            .languages
10475            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10476        if let Some(file_ops_caps) = language_server
10477            .capabilities()
10478            .workspace
10479            .as_ref()
10480            .and_then(|ws| ws.file_operations.as_ref())
10481        {
10482            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10483            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10484            if did_rename_caps.or(will_rename_caps).is_some() {
10485                let watcher = RenamePathsWatchedForServer::default()
10486                    .with_did_rename_patterns(did_rename_caps)
10487                    .with_will_rename_patterns(will_rename_caps);
10488                local
10489                    .language_server_paths_watched_for_rename
10490                    .insert(server_id, watcher);
10491            }
10492        }
10493
10494        self.language_server_statuses.insert(
10495            server_id,
10496            LanguageServerStatus {
10497                name: language_server.name(),
10498                pending_work: Default::default(),
10499                has_pending_diagnostic_updates: false,
10500                progress_tokens: Default::default(),
10501                worktree: Some(key.worktree_id),
10502            },
10503        );
10504
10505        cx.emit(LspStoreEvent::LanguageServerAdded(
10506            server_id,
10507            language_server.name(),
10508            Some(key.worktree_id),
10509        ));
10510        cx.emit(LspStoreEvent::RefreshInlayHints);
10511
10512        let server_capabilities = language_server.capabilities();
10513        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10514            downstream_client
10515                .send(proto::StartLanguageServer {
10516                    project_id: *project_id,
10517                    server: Some(proto::LanguageServer {
10518                        id: server_id.to_proto(),
10519                        name: language_server.name().to_string(),
10520                        worktree_id: Some(key.worktree_id.to_proto()),
10521                    }),
10522                    capabilities: serde_json::to_string(&server_capabilities)
10523                        .expect("serializing server LSP capabilities"),
10524                })
10525                .log_err();
10526        }
10527        self.lsp_server_capabilities
10528            .insert(server_id, server_capabilities);
10529
10530        // Tell the language server about every open buffer in the worktree that matches the language.
10531        // Also check for buffers in worktrees that reused this server
10532        let mut worktrees_using_server = vec![key.worktree_id];
10533        if let Some(local) = self.as_local() {
10534            // Find all worktrees that have this server in their language server tree
10535            for (worktree_id, servers) in &local.lsp_tree.instances {
10536                if *worktree_id != key.worktree_id {
10537                    for server_map in servers.roots.values() {
10538                        if server_map.contains_key(&key.name) {
10539                            worktrees_using_server.push(*worktree_id);
10540                        }
10541                    }
10542                }
10543            }
10544        }
10545
10546        let mut buffer_paths_registered = Vec::new();
10547        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10548            for buffer_handle in buffer_store.buffers() {
10549                let buffer = buffer_handle.read(cx);
10550                let file = match File::from_dyn(buffer.file()) {
10551                    Some(file) => file,
10552                    None => continue,
10553                };
10554                let language = match buffer.language() {
10555                    Some(language) => language,
10556                    None => continue,
10557                };
10558
10559                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10560                    || !self
10561                        .languages
10562                        .lsp_adapters(&language.name())
10563                        .iter()
10564                        .any(|a| a.name == key.name)
10565                {
10566                    continue;
10567                }
10568                // didOpen
10569                let file = match file.as_local() {
10570                    Some(file) => file,
10571                    None => continue,
10572                };
10573
10574                let local = self.as_local_mut().unwrap();
10575
10576                let buffer_id = buffer.remote_id();
10577                if local.registered_buffers.contains_key(&buffer_id) {
10578                    let versions = local
10579                        .buffer_snapshots
10580                        .entry(buffer_id)
10581                        .or_default()
10582                        .entry(server_id)
10583                        .and_modify(|_| {
10584                            assert!(
10585                            false,
10586                            "There should not be an existing snapshot for a newly inserted buffer"
10587                        )
10588                        })
10589                        .or_insert_with(|| {
10590                            vec![LspBufferSnapshot {
10591                                version: 0,
10592                                snapshot: buffer.text_snapshot(),
10593                            }]
10594                        });
10595
10596                    let snapshot = versions.last().unwrap();
10597                    let version = snapshot.version;
10598                    let initial_snapshot = &snapshot.snapshot;
10599                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
10600                    language_server.register_buffer(
10601                        uri,
10602                        adapter.language_id(&language.name()),
10603                        version,
10604                        initial_snapshot.text(),
10605                    );
10606                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10607                    local
10608                        .buffers_opened_in_servers
10609                        .entry(buffer_id)
10610                        .or_default()
10611                        .insert(server_id);
10612                }
10613                buffer_handle.update(cx, |buffer, cx| {
10614                    buffer.set_completion_triggers(
10615                        server_id,
10616                        language_server
10617                            .capabilities()
10618                            .completion_provider
10619                            .as_ref()
10620                            .and_then(|provider| {
10621                                provider
10622                                    .trigger_characters
10623                                    .as_ref()
10624                                    .map(|characters| characters.iter().cloned().collect())
10625                            })
10626                            .unwrap_or_default(),
10627                        cx,
10628                    )
10629                });
10630            }
10631        });
10632
10633        for (buffer_id, abs_path) in buffer_paths_registered {
10634            cx.emit(LspStoreEvent::LanguageServerUpdate {
10635                language_server_id: server_id,
10636                name: Some(adapter.name()),
10637                message: proto::update_language_server::Variant::RegisteredForBuffer(
10638                    proto::RegisteredForBuffer {
10639                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10640                        buffer_id: buffer_id.to_proto(),
10641                    },
10642                ),
10643            });
10644        }
10645
10646        cx.notify();
10647    }
10648
10649    pub fn language_servers_running_disk_based_diagnostics(
10650        &self,
10651    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10652        self.language_server_statuses
10653            .iter()
10654            .filter_map(|(id, status)| {
10655                if status.has_pending_diagnostic_updates {
10656                    Some(*id)
10657                } else {
10658                    None
10659                }
10660            })
10661    }
10662
10663    pub(crate) fn cancel_language_server_work_for_buffers(
10664        &mut self,
10665        buffers: impl IntoIterator<Item = Entity<Buffer>>,
10666        cx: &mut Context<Self>,
10667    ) {
10668        if let Some((client, project_id)) = self.upstream_client() {
10669            let request = client.request(proto::CancelLanguageServerWork {
10670                project_id,
10671                work: Some(proto::cancel_language_server_work::Work::Buffers(
10672                    proto::cancel_language_server_work::Buffers {
10673                        buffer_ids: buffers
10674                            .into_iter()
10675                            .map(|b| b.read(cx).remote_id().to_proto())
10676                            .collect(),
10677                    },
10678                )),
10679            });
10680            cx.background_spawn(request).detach_and_log_err(cx);
10681        } else if let Some(local) = self.as_local() {
10682            let servers = buffers
10683                .into_iter()
10684                .flat_map(|buffer| {
10685                    buffer.update(cx, |buffer, cx| {
10686                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
10687                    })
10688                })
10689                .collect::<HashSet<_>>();
10690            for server_id in servers {
10691                self.cancel_language_server_work(server_id, None, cx);
10692            }
10693        }
10694    }
10695
10696    pub(crate) fn cancel_language_server_work(
10697        &mut self,
10698        server_id: LanguageServerId,
10699        token_to_cancel: Option<String>,
10700        cx: &mut Context<Self>,
10701    ) {
10702        if let Some(local) = self.as_local() {
10703            let status = self.language_server_statuses.get(&server_id);
10704            let server = local.language_servers.get(&server_id);
10705            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
10706            {
10707                for (token, progress) in &status.pending_work {
10708                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
10709                        && token != token_to_cancel
10710                    {
10711                        continue;
10712                    }
10713                    if progress.is_cancellable {
10714                        server
10715                            .notify::<lsp::notification::WorkDoneProgressCancel>(
10716                                &WorkDoneProgressCancelParams {
10717                                    token: lsp::NumberOrString::String(token.clone()),
10718                                },
10719                            )
10720                            .ok();
10721                    }
10722                }
10723            }
10724        } else if let Some((client, project_id)) = self.upstream_client() {
10725            let request = client.request(proto::CancelLanguageServerWork {
10726                project_id,
10727                work: Some(
10728                    proto::cancel_language_server_work::Work::LanguageServerWork(
10729                        proto::cancel_language_server_work::LanguageServerWork {
10730                            language_server_id: server_id.to_proto(),
10731                            token: token_to_cancel,
10732                        },
10733                    ),
10734                ),
10735            });
10736            cx.background_spawn(request).detach_and_log_err(cx);
10737        }
10738    }
10739
10740    fn register_supplementary_language_server(
10741        &mut self,
10742        id: LanguageServerId,
10743        name: LanguageServerName,
10744        server: Arc<LanguageServer>,
10745        cx: &mut Context<Self>,
10746    ) {
10747        if let Some(local) = self.as_local_mut() {
10748            local
10749                .supplementary_language_servers
10750                .insert(id, (name.clone(), server));
10751            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
10752        }
10753    }
10754
10755    fn unregister_supplementary_language_server(
10756        &mut self,
10757        id: LanguageServerId,
10758        cx: &mut Context<Self>,
10759    ) {
10760        if let Some(local) = self.as_local_mut() {
10761            local.supplementary_language_servers.remove(&id);
10762            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
10763        }
10764    }
10765
10766    pub(crate) fn supplementary_language_servers(
10767        &self,
10768    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
10769        self.as_local().into_iter().flat_map(|local| {
10770            local
10771                .supplementary_language_servers
10772                .iter()
10773                .map(|(id, (name, _))| (*id, name.clone()))
10774        })
10775    }
10776
10777    pub fn language_server_adapter_for_id(
10778        &self,
10779        id: LanguageServerId,
10780    ) -> Option<Arc<CachedLspAdapter>> {
10781        self.as_local()
10782            .and_then(|local| local.language_servers.get(&id))
10783            .and_then(|language_server_state| match language_server_state {
10784                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
10785                _ => None,
10786            })
10787    }
10788
10789    pub(super) fn update_local_worktree_language_servers(
10790        &mut self,
10791        worktree_handle: &Entity<Worktree>,
10792        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
10793        cx: &mut Context<Self>,
10794    ) {
10795        if changes.is_empty() {
10796            return;
10797        }
10798
10799        let Some(local) = self.as_local() else { return };
10800
10801        local.prettier_store.update(cx, |prettier_store, cx| {
10802            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
10803        });
10804
10805        let worktree_id = worktree_handle.read(cx).id();
10806        let mut language_server_ids = local
10807            .language_server_ids
10808            .iter()
10809            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
10810            .collect::<Vec<_>>();
10811        language_server_ids.sort();
10812        language_server_ids.dedup();
10813
10814        let abs_path = worktree_handle.read(cx).abs_path();
10815        for server_id in &language_server_ids {
10816            if let Some(LanguageServerState::Running { server, .. }) =
10817                local.language_servers.get(server_id)
10818                && let Some(watched_paths) = local
10819                    .language_server_watched_paths
10820                    .get(server_id)
10821                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
10822            {
10823                let params = lsp::DidChangeWatchedFilesParams {
10824                    changes: changes
10825                        .iter()
10826                        .filter_map(|(path, _, change)| {
10827                            if !watched_paths.is_match(path) {
10828                                return None;
10829                            }
10830                            let typ = match change {
10831                                PathChange::Loaded => return None,
10832                                PathChange::Added => lsp::FileChangeType::CREATED,
10833                                PathChange::Removed => lsp::FileChangeType::DELETED,
10834                                PathChange::Updated => lsp::FileChangeType::CHANGED,
10835                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
10836                            };
10837                            Some(lsp::FileEvent {
10838                                uri: lsp::Uri::from_file_path(abs_path.join(path)).unwrap(),
10839                                typ,
10840                            })
10841                        })
10842                        .collect(),
10843                };
10844                if !params.changes.is_empty() {
10845                    server
10846                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
10847                        .ok();
10848                }
10849            }
10850        }
10851        for (path, _, _) in changes {
10852            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
10853                && local.watched_manifest_filenames.contains(file_name)
10854            {
10855                self.request_workspace_config_refresh();
10856                break;
10857            }
10858        }
10859    }
10860
10861    pub fn wait_for_remote_buffer(
10862        &mut self,
10863        id: BufferId,
10864        cx: &mut Context<Self>,
10865    ) -> Task<Result<Entity<Buffer>>> {
10866        self.buffer_store.update(cx, |buffer_store, cx| {
10867            buffer_store.wait_for_remote_buffer(id, cx)
10868        })
10869    }
10870
10871    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
10872        proto::Symbol {
10873            language_server_name: symbol.language_server_name.0.to_string(),
10874            source_worktree_id: symbol.source_worktree_id.to_proto(),
10875            language_server_id: symbol.source_language_server_id.to_proto(),
10876            worktree_id: symbol.path.worktree_id.to_proto(),
10877            path: symbol.path.path.as_ref().to_proto(),
10878            name: symbol.name.clone(),
10879            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
10880            start: Some(proto::PointUtf16 {
10881                row: symbol.range.start.0.row,
10882                column: symbol.range.start.0.column,
10883            }),
10884            end: Some(proto::PointUtf16 {
10885                row: symbol.range.end.0.row,
10886                column: symbol.range.end.0.column,
10887            }),
10888            signature: symbol.signature.to_vec(),
10889        }
10890    }
10891
10892    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
10893        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
10894        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
10895        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
10896        let path = ProjectPath {
10897            worktree_id,
10898            path: Arc::<Path>::from_proto(serialized_symbol.path),
10899        };
10900
10901        let start = serialized_symbol.start.context("invalid start")?;
10902        let end = serialized_symbol.end.context("invalid end")?;
10903        Ok(CoreSymbol {
10904            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
10905            source_worktree_id,
10906            source_language_server_id: LanguageServerId::from_proto(
10907                serialized_symbol.language_server_id,
10908            ),
10909            path,
10910            name: serialized_symbol.name,
10911            range: Unclipped(PointUtf16::new(start.row, start.column))
10912                ..Unclipped(PointUtf16::new(end.row, end.column)),
10913            kind,
10914            signature: serialized_symbol
10915                .signature
10916                .try_into()
10917                .map_err(|_| anyhow!("invalid signature"))?,
10918        })
10919    }
10920
10921    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
10922        let mut serialized_completion = proto::Completion {
10923            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
10924            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
10925            new_text: completion.new_text.clone(),
10926            ..proto::Completion::default()
10927        };
10928        match &completion.source {
10929            CompletionSource::Lsp {
10930                insert_range,
10931                server_id,
10932                lsp_completion,
10933                lsp_defaults,
10934                resolved,
10935            } => {
10936                let (old_insert_start, old_insert_end) = insert_range
10937                    .as_ref()
10938                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
10939                    .unzip();
10940
10941                serialized_completion.old_insert_start = old_insert_start;
10942                serialized_completion.old_insert_end = old_insert_end;
10943                serialized_completion.source = proto::completion::Source::Lsp as i32;
10944                serialized_completion.server_id = server_id.0 as u64;
10945                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
10946                serialized_completion.lsp_defaults = lsp_defaults
10947                    .as_deref()
10948                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
10949                serialized_completion.resolved = *resolved;
10950            }
10951            CompletionSource::BufferWord {
10952                word_range,
10953                resolved,
10954            } => {
10955                serialized_completion.source = proto::completion::Source::BufferWord as i32;
10956                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
10957                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
10958                serialized_completion.resolved = *resolved;
10959            }
10960            CompletionSource::Custom => {
10961                serialized_completion.source = proto::completion::Source::Custom as i32;
10962                serialized_completion.resolved = true;
10963            }
10964            CompletionSource::Dap { sort_text } => {
10965                serialized_completion.source = proto::completion::Source::Dap as i32;
10966                serialized_completion.sort_text = Some(sort_text.clone());
10967            }
10968        }
10969
10970        serialized_completion
10971    }
10972
10973    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
10974        let old_replace_start = completion
10975            .old_replace_start
10976            .and_then(deserialize_anchor)
10977            .context("invalid old start")?;
10978        let old_replace_end = completion
10979            .old_replace_end
10980            .and_then(deserialize_anchor)
10981            .context("invalid old end")?;
10982        let insert_range = {
10983            match completion.old_insert_start.zip(completion.old_insert_end) {
10984                Some((start, end)) => {
10985                    let start = deserialize_anchor(start).context("invalid insert old start")?;
10986                    let end = deserialize_anchor(end).context("invalid insert old end")?;
10987                    Some(start..end)
10988                }
10989                None => None,
10990            }
10991        };
10992        Ok(CoreCompletion {
10993            replace_range: old_replace_start..old_replace_end,
10994            new_text: completion.new_text,
10995            source: match proto::completion::Source::from_i32(completion.source) {
10996                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
10997                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
10998                    insert_range,
10999                    server_id: LanguageServerId::from_proto(completion.server_id),
11000                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11001                    lsp_defaults: completion
11002                        .lsp_defaults
11003                        .as_deref()
11004                        .map(serde_json::from_slice)
11005                        .transpose()?,
11006                    resolved: completion.resolved,
11007                },
11008                Some(proto::completion::Source::BufferWord) => {
11009                    let word_range = completion
11010                        .buffer_word_start
11011                        .and_then(deserialize_anchor)
11012                        .context("invalid buffer word start")?
11013                        ..completion
11014                            .buffer_word_end
11015                            .and_then(deserialize_anchor)
11016                            .context("invalid buffer word end")?;
11017                    CompletionSource::BufferWord {
11018                        word_range,
11019                        resolved: completion.resolved,
11020                    }
11021                }
11022                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11023                    sort_text: completion
11024                        .sort_text
11025                        .context("expected sort text to exist")?,
11026                },
11027                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11028            },
11029        })
11030    }
11031
11032    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11033        let (kind, lsp_action) = match &action.lsp_action {
11034            LspAction::Action(code_action) => (
11035                proto::code_action::Kind::Action as i32,
11036                serde_json::to_vec(code_action).unwrap(),
11037            ),
11038            LspAction::Command(command) => (
11039                proto::code_action::Kind::Command as i32,
11040                serde_json::to_vec(command).unwrap(),
11041            ),
11042            LspAction::CodeLens(code_lens) => (
11043                proto::code_action::Kind::CodeLens as i32,
11044                serde_json::to_vec(code_lens).unwrap(),
11045            ),
11046        };
11047
11048        proto::CodeAction {
11049            server_id: action.server_id.0 as u64,
11050            start: Some(serialize_anchor(&action.range.start)),
11051            end: Some(serialize_anchor(&action.range.end)),
11052            lsp_action,
11053            kind,
11054            resolved: action.resolved,
11055        }
11056    }
11057
11058    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11059        let start = action
11060            .start
11061            .and_then(deserialize_anchor)
11062            .context("invalid start")?;
11063        let end = action
11064            .end
11065            .and_then(deserialize_anchor)
11066            .context("invalid end")?;
11067        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11068            Some(proto::code_action::Kind::Action) => {
11069                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11070            }
11071            Some(proto::code_action::Kind::Command) => {
11072                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11073            }
11074            Some(proto::code_action::Kind::CodeLens) => {
11075                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11076            }
11077            None => anyhow::bail!("Unknown action kind {}", action.kind),
11078        };
11079        Ok(CodeAction {
11080            server_id: LanguageServerId(action.server_id as usize),
11081            range: start..end,
11082            resolved: action.resolved,
11083            lsp_action,
11084        })
11085    }
11086
11087    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11088        match &formatting_result {
11089            Ok(_) => self.last_formatting_failure = None,
11090            Err(error) => {
11091                let error_string = format!("{error:#}");
11092                log::error!("Formatting failed: {error_string}");
11093                self.last_formatting_failure
11094                    .replace(error_string.lines().join(" "));
11095            }
11096        }
11097    }
11098
11099    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11100        self.lsp_server_capabilities.remove(&for_server);
11101        for buffer_colors in self.lsp_document_colors.values_mut() {
11102            buffer_colors.colors.remove(&for_server);
11103            buffer_colors.cache_version += 1;
11104        }
11105        for buffer_lens in self.lsp_code_lens.values_mut() {
11106            buffer_lens.lens.remove(&for_server);
11107        }
11108        if let Some(local) = self.as_local_mut() {
11109            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11110            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11111                buffer_servers.remove(&for_server);
11112            }
11113        }
11114    }
11115
11116    pub fn result_id(
11117        &self,
11118        server_id: LanguageServerId,
11119        buffer_id: BufferId,
11120        cx: &App,
11121    ) -> Option<String> {
11122        let abs_path = self
11123            .buffer_store
11124            .read(cx)
11125            .get(buffer_id)
11126            .and_then(|b| File::from_dyn(b.read(cx).file()))
11127            .map(|f| f.abs_path(cx))?;
11128        self.as_local()?
11129            .buffer_pull_diagnostics_result_ids
11130            .get(&server_id)?
11131            .get(&abs_path)?
11132            .clone()
11133    }
11134
11135    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11136        let Some(local) = self.as_local() else {
11137            return HashMap::default();
11138        };
11139        local
11140            .buffer_pull_diagnostics_result_ids
11141            .get(&server_id)
11142            .into_iter()
11143            .flatten()
11144            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11145            .collect()
11146    }
11147
11148    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11149        if let Some(LanguageServerState::Running {
11150            workspace_refresh_task: Some(workspace_refresh_task),
11151            ..
11152        }) = self
11153            .as_local_mut()
11154            .and_then(|local| local.language_servers.get_mut(&server_id))
11155        {
11156            workspace_refresh_task.refresh_tx.try_send(()).ok();
11157        }
11158    }
11159
11160    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11161        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11162            return;
11163        };
11164        let Some(local) = self.as_local_mut() else {
11165            return;
11166        };
11167
11168        for server_id in buffer.update(cx, |buffer, cx| {
11169            local.language_server_ids_for_buffer(buffer, cx)
11170        }) {
11171            if let Some(LanguageServerState::Running {
11172                workspace_refresh_task: Some(workspace_refresh_task),
11173                ..
11174            }) = local.language_servers.get_mut(&server_id)
11175            {
11176                workspace_refresh_task.refresh_tx.try_send(()).ok();
11177            }
11178        }
11179    }
11180
11181    fn apply_workspace_diagnostic_report(
11182        &mut self,
11183        server_id: LanguageServerId,
11184        report: lsp::WorkspaceDiagnosticReportResult,
11185        cx: &mut Context<Self>,
11186    ) {
11187        let workspace_diagnostics =
11188            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11189        let mut unchanged_buffers = HashSet::default();
11190        let mut changed_buffers = HashSet::default();
11191        let workspace_diagnostics_updates = workspace_diagnostics
11192            .into_iter()
11193            .filter_map(
11194                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11195                    LspPullDiagnostics::Response {
11196                        server_id,
11197                        uri,
11198                        diagnostics,
11199                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11200                    LspPullDiagnostics::Default => None,
11201                },
11202            )
11203            .fold(
11204                HashMap::default(),
11205                |mut acc, (server_id, uri, diagnostics, version)| {
11206                    let (result_id, diagnostics) = match diagnostics {
11207                        PulledDiagnostics::Unchanged { result_id } => {
11208                            unchanged_buffers.insert(uri.clone());
11209                            (Some(result_id), Vec::new())
11210                        }
11211                        PulledDiagnostics::Changed {
11212                            result_id,
11213                            diagnostics,
11214                        } => {
11215                            changed_buffers.insert(uri.clone());
11216                            (result_id, diagnostics)
11217                        }
11218                    };
11219                    let disk_based_sources = Cow::Owned(
11220                        self.language_server_adapter_for_id(server_id)
11221                            .as_ref()
11222                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11223                            .unwrap_or(&[])
11224                            .to_vec(),
11225                    );
11226                    acc.entry(server_id)
11227                        .or_insert_with(Vec::new)
11228                        .push(DocumentDiagnosticsUpdate {
11229                            server_id,
11230                            diagnostics: lsp::PublishDiagnosticsParams {
11231                                uri,
11232                                diagnostics,
11233                                version,
11234                            },
11235                            result_id,
11236                            disk_based_sources,
11237                        });
11238                    acc
11239                },
11240            );
11241
11242        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11243            self.merge_lsp_diagnostics(
11244                DiagnosticSourceKind::Pulled,
11245                diagnostic_updates,
11246                |buffer, old_diagnostic, cx| {
11247                    File::from_dyn(buffer.file())
11248                        .and_then(|file| {
11249                            let abs_path = file.as_local()?.abs_path(cx);
11250                            lsp::Uri::from_file_path(abs_path).ok()
11251                        })
11252                        .is_none_or(|buffer_uri| {
11253                            unchanged_buffers.contains(&buffer_uri)
11254                                || match old_diagnostic.source_kind {
11255                                    DiagnosticSourceKind::Pulled => {
11256                                        !changed_buffers.contains(&buffer_uri)
11257                                    }
11258                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11259                                        true
11260                                    }
11261                                }
11262                        })
11263                },
11264                cx,
11265            )
11266            .log_err();
11267        }
11268    }
11269
11270    fn register_server_capabilities(
11271        &mut self,
11272        server_id: LanguageServerId,
11273        params: lsp::RegistrationParams,
11274        cx: &mut Context<Self>,
11275    ) -> anyhow::Result<()> {
11276        let server = self
11277            .language_server_for_id(server_id)
11278            .with_context(|| format!("no server {server_id} found"))?;
11279        for reg in params.registrations {
11280            match reg.method.as_str() {
11281                "workspace/didChangeWatchedFiles" => {
11282                    if let Some(options) = reg.register_options {
11283                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11284                            let caps = serde_json::from_value(options)?;
11285                            local_lsp_store
11286                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11287                            true
11288                        } else {
11289                            false
11290                        };
11291                        if notify {
11292                            notify_server_capabilities_updated(&server, cx);
11293                        }
11294                    }
11295                }
11296                "workspace/didChangeConfiguration" => {
11297                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11298                }
11299                "workspace/didChangeWorkspaceFolders" => {
11300                    // In this case register options is an empty object, we can ignore it
11301                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11302                        supported: Some(true),
11303                        change_notifications: Some(OneOf::Right(reg.id)),
11304                    };
11305                    server.update_capabilities(|capabilities| {
11306                        capabilities
11307                            .workspace
11308                            .get_or_insert_default()
11309                            .workspace_folders = Some(caps);
11310                    });
11311                    notify_server_capabilities_updated(&server, cx);
11312                }
11313                "workspace/symbol" => {
11314                    let options = parse_register_capabilities(reg)?;
11315                    server.update_capabilities(|capabilities| {
11316                        capabilities.workspace_symbol_provider = Some(options);
11317                    });
11318                    notify_server_capabilities_updated(&server, cx);
11319                }
11320                "workspace/fileOperations" => {
11321                    if let Some(options) = reg.register_options {
11322                        let caps = serde_json::from_value(options)?;
11323                        server.update_capabilities(|capabilities| {
11324                            capabilities
11325                                .workspace
11326                                .get_or_insert_default()
11327                                .file_operations = Some(caps);
11328                        });
11329                        notify_server_capabilities_updated(&server, cx);
11330                    }
11331                }
11332                "workspace/executeCommand" => {
11333                    if let Some(options) = reg.register_options {
11334                        let options = serde_json::from_value(options)?;
11335                        server.update_capabilities(|capabilities| {
11336                            capabilities.execute_command_provider = Some(options);
11337                        });
11338                        notify_server_capabilities_updated(&server, cx);
11339                    }
11340                }
11341                "textDocument/rangeFormatting" => {
11342                    let options = parse_register_capabilities(reg)?;
11343                    server.update_capabilities(|capabilities| {
11344                        capabilities.document_range_formatting_provider = Some(options);
11345                    });
11346                    notify_server_capabilities_updated(&server, cx);
11347                }
11348                "textDocument/onTypeFormatting" => {
11349                    if let Some(options) = reg
11350                        .register_options
11351                        .map(serde_json::from_value)
11352                        .transpose()?
11353                    {
11354                        server.update_capabilities(|capabilities| {
11355                            capabilities.document_on_type_formatting_provider = Some(options);
11356                        });
11357                        notify_server_capabilities_updated(&server, cx);
11358                    }
11359                }
11360                "textDocument/formatting" => {
11361                    let options = parse_register_capabilities(reg)?;
11362                    server.update_capabilities(|capabilities| {
11363                        capabilities.document_formatting_provider = Some(options);
11364                    });
11365                    notify_server_capabilities_updated(&server, cx);
11366                }
11367                "textDocument/rename" => {
11368                    let options = parse_register_capabilities(reg)?;
11369                    server.update_capabilities(|capabilities| {
11370                        capabilities.rename_provider = Some(options);
11371                    });
11372                    notify_server_capabilities_updated(&server, cx);
11373                }
11374                "textDocument/inlayHint" => {
11375                    let options = parse_register_capabilities(reg)?;
11376                    server.update_capabilities(|capabilities| {
11377                        capabilities.inlay_hint_provider = Some(options);
11378                    });
11379                    notify_server_capabilities_updated(&server, cx);
11380                }
11381                "textDocument/documentSymbol" => {
11382                    let options = parse_register_capabilities(reg)?;
11383                    server.update_capabilities(|capabilities| {
11384                        capabilities.document_symbol_provider = Some(options);
11385                    });
11386                    notify_server_capabilities_updated(&server, cx);
11387                }
11388                "textDocument/codeAction" => {
11389                    let options = parse_register_capabilities(reg)?;
11390                    let provider = match options {
11391                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11392                        OneOf::Right(caps) => caps,
11393                    };
11394                    server.update_capabilities(|capabilities| {
11395                        capabilities.code_action_provider = Some(provider);
11396                    });
11397                    notify_server_capabilities_updated(&server, cx);
11398                }
11399                "textDocument/definition" => {
11400                    let options = parse_register_capabilities(reg)?;
11401                    server.update_capabilities(|capabilities| {
11402                        capabilities.definition_provider = Some(options);
11403                    });
11404                    notify_server_capabilities_updated(&server, cx);
11405                }
11406                "textDocument/completion" => {
11407                    if let Some(caps) = reg
11408                        .register_options
11409                        .map(serde_json::from_value)
11410                        .transpose()?
11411                    {
11412                        server.update_capabilities(|capabilities| {
11413                            capabilities.completion_provider = Some(caps);
11414                        });
11415                        notify_server_capabilities_updated(&server, cx);
11416                    }
11417                }
11418                "textDocument/hover" => {
11419                    let options = parse_register_capabilities(reg)?;
11420                    let provider = match options {
11421                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11422                        OneOf::Right(caps) => caps,
11423                    };
11424                    server.update_capabilities(|capabilities| {
11425                        capabilities.hover_provider = Some(provider);
11426                    });
11427                    notify_server_capabilities_updated(&server, cx);
11428                }
11429                "textDocument/signatureHelp" => {
11430                    if let Some(caps) = reg
11431                        .register_options
11432                        .map(serde_json::from_value)
11433                        .transpose()?
11434                    {
11435                        server.update_capabilities(|capabilities| {
11436                            capabilities.signature_help_provider = Some(caps);
11437                        });
11438                        notify_server_capabilities_updated(&server, cx);
11439                    }
11440                }
11441                "textDocument/didChange" => {
11442                    if let Some(sync_kind) = reg
11443                        .register_options
11444                        .and_then(|opts| opts.get("syncKind").cloned())
11445                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11446                        .transpose()?
11447                    {
11448                        server.update_capabilities(|capabilities| {
11449                            let mut sync_options =
11450                                Self::take_text_document_sync_options(capabilities);
11451                            sync_options.change = Some(sync_kind);
11452                            capabilities.text_document_sync =
11453                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11454                        });
11455                        notify_server_capabilities_updated(&server, cx);
11456                    }
11457                }
11458                "textDocument/didSave" => {
11459                    if let Some(include_text) = reg
11460                        .register_options
11461                        .map(|opts| {
11462                            let transpose = opts
11463                                .get("includeText")
11464                                .cloned()
11465                                .map(serde_json::from_value::<Option<bool>>)
11466                                .transpose();
11467                            match transpose {
11468                                Ok(value) => Ok(value.flatten()),
11469                                Err(e) => Err(e),
11470                            }
11471                        })
11472                        .transpose()?
11473                    {
11474                        server.update_capabilities(|capabilities| {
11475                            let mut sync_options =
11476                                Self::take_text_document_sync_options(capabilities);
11477                            sync_options.save =
11478                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11479                                    include_text,
11480                                }));
11481                            capabilities.text_document_sync =
11482                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11483                        });
11484                        notify_server_capabilities_updated(&server, cx);
11485                    }
11486                }
11487                "textDocument/codeLens" => {
11488                    if let Some(caps) = reg
11489                        .register_options
11490                        .map(serde_json::from_value)
11491                        .transpose()?
11492                    {
11493                        server.update_capabilities(|capabilities| {
11494                            capabilities.code_lens_provider = Some(caps);
11495                        });
11496                        notify_server_capabilities_updated(&server, cx);
11497                    }
11498                }
11499                "textDocument/diagnostic" => {
11500                    if let Some(caps) = reg
11501                        .register_options
11502                        .map(serde_json::from_value)
11503                        .transpose()?
11504                    {
11505                        server.update_capabilities(|capabilities| {
11506                            capabilities.diagnostic_provider = Some(caps);
11507                        });
11508                        notify_server_capabilities_updated(&server, cx);
11509                    }
11510                }
11511                "textDocument/documentColor" => {
11512                    let options = parse_register_capabilities(reg)?;
11513                    let provider = match options {
11514                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11515                        OneOf::Right(caps) => caps,
11516                    };
11517                    server.update_capabilities(|capabilities| {
11518                        capabilities.color_provider = Some(provider);
11519                    });
11520                    notify_server_capabilities_updated(&server, cx);
11521                }
11522                _ => log::warn!("unhandled capability registration: {reg:?}"),
11523            }
11524        }
11525
11526        Ok(())
11527    }
11528
11529    fn unregister_server_capabilities(
11530        &mut self,
11531        server_id: LanguageServerId,
11532        params: lsp::UnregistrationParams,
11533        cx: &mut Context<Self>,
11534    ) -> anyhow::Result<()> {
11535        let server = self
11536            .language_server_for_id(server_id)
11537            .with_context(|| format!("no server {server_id} found"))?;
11538        for unreg in params.unregisterations.iter() {
11539            match unreg.method.as_str() {
11540                "workspace/didChangeWatchedFiles" => {
11541                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11542                        local_lsp_store
11543                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11544                        true
11545                    } else {
11546                        false
11547                    };
11548                    if notify {
11549                        notify_server_capabilities_updated(&server, cx);
11550                    }
11551                }
11552                "workspace/didChangeConfiguration" => {
11553                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11554                }
11555                "workspace/didChangeWorkspaceFolders" => {
11556                    server.update_capabilities(|capabilities| {
11557                        capabilities
11558                            .workspace
11559                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11560                                workspace_folders: None,
11561                                file_operations: None,
11562                            })
11563                            .workspace_folders = None;
11564                    });
11565                    notify_server_capabilities_updated(&server, cx);
11566                }
11567                "workspace/symbol" => {
11568                    server.update_capabilities(|capabilities| {
11569                        capabilities.workspace_symbol_provider = None
11570                    });
11571                    notify_server_capabilities_updated(&server, cx);
11572                }
11573                "workspace/fileOperations" => {
11574                    server.update_capabilities(|capabilities| {
11575                        capabilities
11576                            .workspace
11577                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11578                                workspace_folders: None,
11579                                file_operations: None,
11580                            })
11581                            .file_operations = None;
11582                    });
11583                    notify_server_capabilities_updated(&server, cx);
11584                }
11585                "workspace/executeCommand" => {
11586                    server.update_capabilities(|capabilities| {
11587                        capabilities.execute_command_provider = None;
11588                    });
11589                    notify_server_capabilities_updated(&server, cx);
11590                }
11591                "textDocument/rangeFormatting" => {
11592                    server.update_capabilities(|capabilities| {
11593                        capabilities.document_range_formatting_provider = None
11594                    });
11595                    notify_server_capabilities_updated(&server, cx);
11596                }
11597                "textDocument/onTypeFormatting" => {
11598                    server.update_capabilities(|capabilities| {
11599                        capabilities.document_on_type_formatting_provider = None;
11600                    });
11601                    notify_server_capabilities_updated(&server, cx);
11602                }
11603                "textDocument/formatting" => {
11604                    server.update_capabilities(|capabilities| {
11605                        capabilities.document_formatting_provider = None;
11606                    });
11607                    notify_server_capabilities_updated(&server, cx);
11608                }
11609                "textDocument/rename" => {
11610                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11611                    notify_server_capabilities_updated(&server, cx);
11612                }
11613                "textDocument/codeAction" => {
11614                    server.update_capabilities(|capabilities| {
11615                        capabilities.code_action_provider = None;
11616                    });
11617                    notify_server_capabilities_updated(&server, cx);
11618                }
11619                "textDocument/definition" => {
11620                    server.update_capabilities(|capabilities| {
11621                        capabilities.definition_provider = None;
11622                    });
11623                    notify_server_capabilities_updated(&server, cx);
11624                }
11625                "textDocument/completion" => {
11626                    server.update_capabilities(|capabilities| {
11627                        capabilities.completion_provider = None;
11628                    });
11629                    notify_server_capabilities_updated(&server, cx);
11630                }
11631                "textDocument/hover" => {
11632                    server.update_capabilities(|capabilities| {
11633                        capabilities.hover_provider = None;
11634                    });
11635                    notify_server_capabilities_updated(&server, cx);
11636                }
11637                "textDocument/signatureHelp" => {
11638                    server.update_capabilities(|capabilities| {
11639                        capabilities.signature_help_provider = None;
11640                    });
11641                    notify_server_capabilities_updated(&server, cx);
11642                }
11643                "textDocument/didChange" => {
11644                    server.update_capabilities(|capabilities| {
11645                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11646                        sync_options.change = None;
11647                        capabilities.text_document_sync =
11648                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11649                    });
11650                    notify_server_capabilities_updated(&server, cx);
11651                }
11652                "textDocument/didSave" => {
11653                    server.update_capabilities(|capabilities| {
11654                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11655                        sync_options.save = None;
11656                        capabilities.text_document_sync =
11657                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11658                    });
11659                    notify_server_capabilities_updated(&server, cx);
11660                }
11661                "textDocument/codeLens" => {
11662                    server.update_capabilities(|capabilities| {
11663                        capabilities.code_lens_provider = None;
11664                    });
11665                    notify_server_capabilities_updated(&server, cx);
11666                }
11667                "textDocument/diagnostic" => {
11668                    server.update_capabilities(|capabilities| {
11669                        capabilities.diagnostic_provider = None;
11670                    });
11671                    notify_server_capabilities_updated(&server, cx);
11672                }
11673                "textDocument/documentColor" => {
11674                    server.update_capabilities(|capabilities| {
11675                        capabilities.color_provider = None;
11676                    });
11677                    notify_server_capabilities_updated(&server, cx);
11678                }
11679                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
11680            }
11681        }
11682
11683        Ok(())
11684    }
11685
11686    async fn query_lsp_locally<T>(
11687        lsp_store: Entity<Self>,
11688        sender_id: proto::PeerId,
11689        lsp_request_id: LspRequestId,
11690        proto_request: T::ProtoRequest,
11691        position: Option<Anchor>,
11692        mut cx: AsyncApp,
11693    ) -> Result<()>
11694    where
11695        T: LspCommand + Clone,
11696        T::ProtoRequest: proto::LspRequestMessage,
11697        <T::ProtoRequest as proto::RequestMessage>::Response:
11698            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
11699    {
11700        let buffer_id = BufferId::new(proto_request.buffer_id())?;
11701        let version = deserialize_version(proto_request.buffer_version());
11702        let buffer = lsp_store.update(&mut cx, |this, cx| {
11703            this.buffer_store.read(cx).get_existing(buffer_id)
11704        })??;
11705        buffer
11706            .update(&mut cx, |buffer, _| {
11707                buffer.wait_for_version(version.clone())
11708            })?
11709            .await?;
11710        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
11711        let request =
11712            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
11713        lsp_store.update(&mut cx, |lsp_store, cx| {
11714            let request_task =
11715                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
11716            let existing_queries = lsp_store
11717                .running_lsp_requests
11718                .entry(TypeId::of::<T>())
11719                .or_default();
11720            if T::ProtoRequest::stop_previous_requests()
11721                || buffer_version.changed_since(&existing_queries.0)
11722            {
11723                existing_queries.1.clear();
11724            }
11725            existing_queries.1.insert(
11726                lsp_request_id,
11727                cx.spawn(async move |lsp_store, cx| {
11728                    let response = request_task.await;
11729                    lsp_store
11730                        .update(cx, |lsp_store, cx| {
11731                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
11732                            {
11733                                let response = response
11734                                    .into_iter()
11735                                    .map(|(server_id, response)| {
11736                                        (
11737                                            server_id.to_proto(),
11738                                            T::response_to_proto(
11739                                                response,
11740                                                lsp_store,
11741                                                sender_id,
11742                                                &buffer_version,
11743                                                cx,
11744                                            )
11745                                            .into(),
11746                                        )
11747                                    })
11748                                    .collect::<HashMap<_, _>>();
11749                                match client.send_lsp_response::<T::ProtoRequest>(
11750                                    project_id,
11751                                    lsp_request_id,
11752                                    response,
11753                                ) {
11754                                    Ok(()) => {}
11755                                    Err(e) => {
11756                                        log::error!("Failed to send LSP response: {e:#}",)
11757                                    }
11758                                }
11759                            }
11760                        })
11761                        .ok();
11762                }),
11763            );
11764        })?;
11765        Ok(())
11766    }
11767
11768    fn take_text_document_sync_options(
11769        capabilities: &mut lsp::ServerCapabilities,
11770    ) -> lsp::TextDocumentSyncOptions {
11771        match capabilities.text_document_sync.take() {
11772            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
11773            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
11774                let mut sync_options = lsp::TextDocumentSyncOptions::default();
11775                sync_options.change = Some(sync_kind);
11776                sync_options
11777            }
11778            None => lsp::TextDocumentSyncOptions::default(),
11779        }
11780    }
11781
11782    #[cfg(any(test, feature = "test-support"))]
11783    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
11784        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
11785        Some(data.update.take()?.1)
11786    }
11787
11788    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
11789        self.downstream_client.clone()
11790    }
11791
11792    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
11793        self.worktree_store.clone()
11794    }
11795}
11796
11797// Registration with registerOptions as null, should fallback to true.
11798// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
11799fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
11800    reg: lsp::Registration,
11801) -> Result<OneOf<bool, T>> {
11802    Ok(match reg.register_options {
11803        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
11804        None => OneOf::Left(true),
11805    })
11806}
11807
11808fn subscribe_to_binary_statuses(
11809    languages: &Arc<LanguageRegistry>,
11810    cx: &mut Context<'_, LspStore>,
11811) -> Task<()> {
11812    let mut server_statuses = languages.language_server_binary_statuses();
11813    cx.spawn(async move |lsp_store, cx| {
11814        while let Some((server_name, binary_status)) = server_statuses.next().await {
11815            if lsp_store
11816                .update(cx, |_, cx| {
11817                    let mut message = None;
11818                    let binary_status = match binary_status {
11819                        BinaryStatus::None => proto::ServerBinaryStatus::None,
11820                        BinaryStatus::CheckingForUpdate => {
11821                            proto::ServerBinaryStatus::CheckingForUpdate
11822                        }
11823                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
11824                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
11825                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
11826                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
11827                        BinaryStatus::Failed { error } => {
11828                            message = Some(error);
11829                            proto::ServerBinaryStatus::Failed
11830                        }
11831                    };
11832                    cx.emit(LspStoreEvent::LanguageServerUpdate {
11833                        // Binary updates are about the binary that might not have any language server id at that point.
11834                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
11835                        language_server_id: LanguageServerId(0),
11836                        name: Some(server_name),
11837                        message: proto::update_language_server::Variant::StatusUpdate(
11838                            proto::StatusUpdate {
11839                                message,
11840                                status: Some(proto::status_update::Status::Binary(
11841                                    binary_status as i32,
11842                                )),
11843                            },
11844                        ),
11845                    });
11846                })
11847                .is_err()
11848            {
11849                break;
11850            }
11851        }
11852    })
11853}
11854
11855fn lsp_workspace_diagnostics_refresh(
11856    server: Arc<LanguageServer>,
11857    cx: &mut Context<'_, LspStore>,
11858) -> Option<WorkspaceRefreshTask> {
11859    let identifier = match server.capabilities().diagnostic_provider? {
11860        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
11861            if !diagnostic_options.workspace_diagnostics {
11862                return None;
11863            }
11864            diagnostic_options.identifier
11865        }
11866        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
11867            let diagnostic_options = registration_options.diagnostic_options;
11868            if !diagnostic_options.workspace_diagnostics {
11869                return None;
11870            }
11871            diagnostic_options.identifier
11872        }
11873    };
11874
11875    let (progress_tx, mut progress_rx) = mpsc::channel(1);
11876    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
11877    refresh_tx.try_send(()).ok();
11878
11879    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
11880        let mut attempts = 0;
11881        let max_attempts = 50;
11882        let mut requests = 0;
11883
11884        loop {
11885            let Some(()) = refresh_rx.recv().await else {
11886                return;
11887            };
11888
11889            'request: loop {
11890                requests += 1;
11891                if attempts > max_attempts {
11892                    log::error!(
11893                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
11894                    );
11895                    return;
11896                }
11897                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
11898                cx.background_executor()
11899                    .timer(Duration::from_millis(backoff_millis))
11900                    .await;
11901                attempts += 1;
11902
11903                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
11904                    lsp_store
11905                        .all_result_ids(server.server_id())
11906                        .into_iter()
11907                        .filter_map(|(abs_path, result_id)| {
11908                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
11909                            Some(lsp::PreviousResultId {
11910                                uri,
11911                                value: result_id,
11912                            })
11913                        })
11914                        .collect()
11915                }) else {
11916                    return;
11917                };
11918
11919                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
11920
11921                progress_rx.try_recv().ok();
11922                let timer =
11923                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
11924                let progress = pin!(progress_rx.recv().fuse());
11925                let response_result = server
11926                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
11927                        lsp::WorkspaceDiagnosticParams {
11928                            previous_result_ids,
11929                            identifier: identifier.clone(),
11930                            work_done_progress_params: Default::default(),
11931                            partial_result_params: lsp::PartialResultParams {
11932                                partial_result_token: Some(lsp::ProgressToken::String(token)),
11933                            },
11934                        },
11935                        select(timer, progress).then(|either| match either {
11936                            Either::Left((message, ..)) => ready(message).left_future(),
11937                            Either::Right(..) => pending::<String>().right_future(),
11938                        }),
11939                    )
11940                    .await;
11941
11942                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
11943                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
11944                match response_result {
11945                    ConnectionResult::Timeout => {
11946                        log::error!("Timeout during workspace diagnostics pull");
11947                        continue 'request;
11948                    }
11949                    ConnectionResult::ConnectionReset => {
11950                        log::error!("Server closed a workspace diagnostics pull request");
11951                        continue 'request;
11952                    }
11953                    ConnectionResult::Result(Err(e)) => {
11954                        log::error!("Error during workspace diagnostics pull: {e:#}");
11955                        break 'request;
11956                    }
11957                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
11958                        attempts = 0;
11959                        if lsp_store
11960                            .update(cx, |lsp_store, cx| {
11961                                lsp_store.apply_workspace_diagnostic_report(
11962                                    server.server_id(),
11963                                    pulled_diagnostics,
11964                                    cx,
11965                                )
11966                            })
11967                            .is_err()
11968                        {
11969                            return;
11970                        }
11971                        break 'request;
11972                    }
11973                }
11974            }
11975        }
11976    });
11977
11978    Some(WorkspaceRefreshTask {
11979        refresh_tx,
11980        progress_tx,
11981        task: workspace_query_language_server,
11982    })
11983}
11984
11985fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
11986    let CompletionSource::BufferWord {
11987        word_range,
11988        resolved,
11989    } = &mut completion.source
11990    else {
11991        return;
11992    };
11993    if *resolved {
11994        return;
11995    }
11996
11997    if completion.new_text
11998        != snapshot
11999            .text_for_range(word_range.clone())
12000            .collect::<String>()
12001    {
12002        return;
12003    }
12004
12005    let mut offset = 0;
12006    for chunk in snapshot.chunks(word_range.clone(), true) {
12007        let end_offset = offset + chunk.text.len();
12008        if let Some(highlight_id) = chunk.syntax_highlight_id {
12009            completion
12010                .label
12011                .runs
12012                .push((offset..end_offset, highlight_id));
12013        }
12014        offset = end_offset;
12015    }
12016    *resolved = true;
12017}
12018
12019impl EventEmitter<LspStoreEvent> for LspStore {}
12020
12021fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12022    hover
12023        .contents
12024        .retain(|hover_block| !hover_block.text.trim().is_empty());
12025    if hover.contents.is_empty() {
12026        None
12027    } else {
12028        Some(hover)
12029    }
12030}
12031
12032async fn populate_labels_for_completions(
12033    new_completions: Vec<CoreCompletion>,
12034    language: Option<Arc<Language>>,
12035    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12036) -> Vec<Completion> {
12037    let lsp_completions = new_completions
12038        .iter()
12039        .filter_map(|new_completion| {
12040            new_completion
12041                .source
12042                .lsp_completion(true)
12043                .map(|lsp_completion| lsp_completion.into_owned())
12044        })
12045        .collect::<Vec<_>>();
12046
12047    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12048        lsp_adapter
12049            .labels_for_completions(&lsp_completions, language)
12050            .await
12051            .log_err()
12052            .unwrap_or_default()
12053    } else {
12054        Vec::new()
12055    }
12056    .into_iter()
12057    .fuse();
12058
12059    let mut completions = Vec::new();
12060    for completion in new_completions {
12061        match completion.source.lsp_completion(true) {
12062            Some(lsp_completion) => {
12063                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12064
12065                let mut label = labels.next().flatten().unwrap_or_else(|| {
12066                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12067                });
12068                ensure_uniform_list_compatible_label(&mut label);
12069                completions.push(Completion {
12070                    label,
12071                    documentation,
12072                    replace_range: completion.replace_range,
12073                    new_text: completion.new_text,
12074                    insert_text_mode: lsp_completion.insert_text_mode,
12075                    source: completion.source,
12076                    icon_path: None,
12077                    confirm: None,
12078                });
12079            }
12080            None => {
12081                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12082                ensure_uniform_list_compatible_label(&mut label);
12083                completions.push(Completion {
12084                    label,
12085                    documentation: None,
12086                    replace_range: completion.replace_range,
12087                    new_text: completion.new_text,
12088                    source: completion.source,
12089                    insert_text_mode: None,
12090                    icon_path: None,
12091                    confirm: None,
12092                });
12093            }
12094        }
12095    }
12096    completions
12097}
12098
12099#[derive(Debug)]
12100pub enum LanguageServerToQuery {
12101    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12102    FirstCapable,
12103    /// Query a specific language server.
12104    Other(LanguageServerId),
12105}
12106
12107#[derive(Default)]
12108struct RenamePathsWatchedForServer {
12109    did_rename: Vec<RenameActionPredicate>,
12110    will_rename: Vec<RenameActionPredicate>,
12111}
12112
12113impl RenamePathsWatchedForServer {
12114    fn with_did_rename_patterns(
12115        mut self,
12116        did_rename: Option<&FileOperationRegistrationOptions>,
12117    ) -> Self {
12118        if let Some(did_rename) = did_rename {
12119            self.did_rename = did_rename
12120                .filters
12121                .iter()
12122                .filter_map(|filter| filter.try_into().log_err())
12123                .collect();
12124        }
12125        self
12126    }
12127    fn with_will_rename_patterns(
12128        mut self,
12129        will_rename: Option<&FileOperationRegistrationOptions>,
12130    ) -> Self {
12131        if let Some(will_rename) = will_rename {
12132            self.will_rename = will_rename
12133                .filters
12134                .iter()
12135                .filter_map(|filter| filter.try_into().log_err())
12136                .collect();
12137        }
12138        self
12139    }
12140
12141    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12142        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12143    }
12144    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12145        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12146    }
12147}
12148
12149impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12150    type Error = globset::Error;
12151    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12152        Ok(Self {
12153            kind: ops.pattern.matches.clone(),
12154            glob: GlobBuilder::new(&ops.pattern.glob)
12155                .case_insensitive(
12156                    ops.pattern
12157                        .options
12158                        .as_ref()
12159                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12160                )
12161                .build()?
12162                .compile_matcher(),
12163        })
12164    }
12165}
12166struct RenameActionPredicate {
12167    glob: GlobMatcher,
12168    kind: Option<FileOperationPatternKind>,
12169}
12170
12171impl RenameActionPredicate {
12172    // Returns true if language server should be notified
12173    fn eval(&self, path: &str, is_dir: bool) -> bool {
12174        self.kind.as_ref().is_none_or(|kind| {
12175            let expected_kind = if is_dir {
12176                FileOperationPatternKind::Folder
12177            } else {
12178                FileOperationPatternKind::File
12179            };
12180            kind == &expected_kind
12181        }) && self.glob.is_match(path)
12182    }
12183}
12184
12185#[derive(Default)]
12186struct LanguageServerWatchedPaths {
12187    worktree_paths: HashMap<WorktreeId, GlobSet>,
12188    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12189}
12190
12191#[derive(Default)]
12192struct LanguageServerWatchedPathsBuilder {
12193    worktree_paths: HashMap<WorktreeId, GlobSet>,
12194    abs_paths: HashMap<Arc<Path>, GlobSet>,
12195}
12196
12197impl LanguageServerWatchedPathsBuilder {
12198    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12199        self.worktree_paths.insert(worktree_id, glob_set);
12200    }
12201    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12202        self.abs_paths.insert(path, glob_set);
12203    }
12204    fn build(
12205        self,
12206        fs: Arc<dyn Fs>,
12207        language_server_id: LanguageServerId,
12208        cx: &mut Context<LspStore>,
12209    ) -> LanguageServerWatchedPaths {
12210        let project = cx.weak_entity();
12211
12212        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12213        let abs_paths = self
12214            .abs_paths
12215            .into_iter()
12216            .map(|(abs_path, globset)| {
12217                let task = cx.spawn({
12218                    let abs_path = abs_path.clone();
12219                    let fs = fs.clone();
12220
12221                    let lsp_store = project.clone();
12222                    async move |_, cx| {
12223                        maybe!(async move {
12224                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12225                            while let Some(update) = push_updates.0.next().await {
12226                                let action = lsp_store
12227                                    .update(cx, |this, _| {
12228                                        let Some(local) = this.as_local() else {
12229                                            return ControlFlow::Break(());
12230                                        };
12231                                        let Some(watcher) = local
12232                                            .language_server_watched_paths
12233                                            .get(&language_server_id)
12234                                        else {
12235                                            return ControlFlow::Break(());
12236                                        };
12237                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12238                                            "Watched abs path is not registered with a watcher",
12239                                        );
12240                                        let matching_entries = update
12241                                            .into_iter()
12242                                            .filter(|event| globs.is_match(&event.path))
12243                                            .collect::<Vec<_>>();
12244                                        this.lsp_notify_abs_paths_changed(
12245                                            language_server_id,
12246                                            matching_entries,
12247                                        );
12248                                        ControlFlow::Continue(())
12249                                    })
12250                                    .ok()?;
12251
12252                                if action.is_break() {
12253                                    break;
12254                                }
12255                            }
12256                            Some(())
12257                        })
12258                        .await;
12259                    }
12260                });
12261                (abs_path, (globset, task))
12262            })
12263            .collect();
12264        LanguageServerWatchedPaths {
12265            worktree_paths: self.worktree_paths,
12266            abs_paths,
12267        }
12268    }
12269}
12270
12271struct LspBufferSnapshot {
12272    version: i32,
12273    snapshot: TextBufferSnapshot,
12274}
12275
12276/// A prompt requested by LSP server.
12277#[derive(Clone, Debug)]
12278pub struct LanguageServerPromptRequest {
12279    pub level: PromptLevel,
12280    pub message: String,
12281    pub actions: Vec<MessageActionItem>,
12282    pub lsp_name: String,
12283    pub(crate) response_channel: Sender<MessageActionItem>,
12284}
12285
12286impl LanguageServerPromptRequest {
12287    pub async fn respond(self, index: usize) -> Option<()> {
12288        if let Some(response) = self.actions.into_iter().nth(index) {
12289            self.response_channel.send(response).await.ok()
12290        } else {
12291            None
12292        }
12293    }
12294}
12295impl PartialEq for LanguageServerPromptRequest {
12296    fn eq(&self, other: &Self) -> bool {
12297        self.message == other.message && self.actions == other.actions
12298    }
12299}
12300
12301#[derive(Clone, Debug, PartialEq)]
12302pub enum LanguageServerLogType {
12303    Log(MessageType),
12304    Trace { verbose_info: Option<String> },
12305    Rpc { received: bool },
12306}
12307
12308impl LanguageServerLogType {
12309    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12310        match self {
12311            Self::Log(log_type) => {
12312                use proto::log_message::LogLevel;
12313                let level = match *log_type {
12314                    MessageType::ERROR => LogLevel::Error,
12315                    MessageType::WARNING => LogLevel::Warning,
12316                    MessageType::INFO => LogLevel::Info,
12317                    MessageType::LOG => LogLevel::Log,
12318                    other => {
12319                        log::warn!("Unknown lsp log message type: {other:?}");
12320                        LogLevel::Log
12321                    }
12322                };
12323                proto::language_server_log::LogType::Log(proto::LogMessage {
12324                    level: level as i32,
12325                })
12326            }
12327            Self::Trace { verbose_info } => {
12328                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12329                    verbose_info: verbose_info.to_owned(),
12330                })
12331            }
12332            Self::Rpc { received } => {
12333                let kind = if *received {
12334                    proto::rpc_message::Kind::Received
12335                } else {
12336                    proto::rpc_message::Kind::Sent
12337                };
12338                let kind = kind as i32;
12339                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12340            }
12341        }
12342    }
12343
12344    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12345        use proto::log_message::LogLevel;
12346        use proto::rpc_message;
12347        match log_type {
12348            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12349                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12350                    LogLevel::Error => MessageType::ERROR,
12351                    LogLevel::Warning => MessageType::WARNING,
12352                    LogLevel::Info => MessageType::INFO,
12353                    LogLevel::Log => MessageType::LOG,
12354                },
12355            ),
12356            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12357                verbose_info: trace_message.verbose_info,
12358            },
12359            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12360                received: match rpc_message::Kind::from_i32(message.kind)
12361                    .unwrap_or(rpc_message::Kind::Received)
12362                {
12363                    rpc_message::Kind::Received => true,
12364                    rpc_message::Kind::Sent => false,
12365                },
12366            },
12367        }
12368    }
12369}
12370
12371pub struct WorkspaceRefreshTask {
12372    refresh_tx: mpsc::Sender<()>,
12373    progress_tx: mpsc::Sender<()>,
12374    #[allow(dead_code)]
12375    task: Task<()>,
12376}
12377
12378pub enum LanguageServerState {
12379    Starting {
12380        startup: Task<Option<Arc<LanguageServer>>>,
12381        /// List of language servers that will be added to the workspace once it's initialization completes.
12382        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12383    },
12384
12385    Running {
12386        adapter: Arc<CachedLspAdapter>,
12387        server: Arc<LanguageServer>,
12388        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12389        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12390    },
12391}
12392
12393impl LanguageServerState {
12394    fn add_workspace_folder(&self, uri: Uri) {
12395        match self {
12396            LanguageServerState::Starting {
12397                pending_workspace_folders,
12398                ..
12399            } => {
12400                pending_workspace_folders.lock().insert(uri);
12401            }
12402            LanguageServerState::Running { server, .. } => {
12403                server.add_workspace_folder(uri);
12404            }
12405        }
12406    }
12407    fn _remove_workspace_folder(&self, uri: Uri) {
12408        match self {
12409            LanguageServerState::Starting {
12410                pending_workspace_folders,
12411                ..
12412            } => {
12413                pending_workspace_folders.lock().remove(&uri);
12414            }
12415            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12416        }
12417    }
12418}
12419
12420impl std::fmt::Debug for LanguageServerState {
12421    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12422        match self {
12423            LanguageServerState::Starting { .. } => {
12424                f.debug_struct("LanguageServerState::Starting").finish()
12425            }
12426            LanguageServerState::Running { .. } => {
12427                f.debug_struct("LanguageServerState::Running").finish()
12428            }
12429        }
12430    }
12431}
12432
12433#[derive(Clone, Debug, Serialize)]
12434pub struct LanguageServerProgress {
12435    pub is_disk_based_diagnostics_progress: bool,
12436    pub is_cancellable: bool,
12437    pub title: Option<String>,
12438    pub message: Option<String>,
12439    pub percentage: Option<usize>,
12440    #[serde(skip_serializing)]
12441    pub last_update_at: Instant,
12442}
12443
12444#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12445pub struct DiagnosticSummary {
12446    pub error_count: usize,
12447    pub warning_count: usize,
12448}
12449
12450impl DiagnosticSummary {
12451    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12452        let mut this = Self {
12453            error_count: 0,
12454            warning_count: 0,
12455        };
12456
12457        for entry in diagnostics {
12458            if entry.diagnostic.is_primary {
12459                match entry.diagnostic.severity {
12460                    DiagnosticSeverity::ERROR => this.error_count += 1,
12461                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12462                    _ => {}
12463                }
12464            }
12465        }
12466
12467        this
12468    }
12469
12470    pub fn is_empty(&self) -> bool {
12471        self.error_count == 0 && self.warning_count == 0
12472    }
12473
12474    pub fn to_proto(
12475        self,
12476        language_server_id: LanguageServerId,
12477        path: &Path,
12478    ) -> proto::DiagnosticSummary {
12479        proto::DiagnosticSummary {
12480            path: path.to_proto(),
12481            language_server_id: language_server_id.0 as u64,
12482            error_count: self.error_count as u32,
12483            warning_count: self.warning_count as u32,
12484        }
12485    }
12486}
12487
12488#[derive(Clone, Debug)]
12489pub enum CompletionDocumentation {
12490    /// There is no documentation for this completion.
12491    Undocumented,
12492    /// A single line of documentation.
12493    SingleLine(SharedString),
12494    /// Multiple lines of plain text documentation.
12495    MultiLinePlainText(SharedString),
12496    /// Markdown documentation.
12497    MultiLineMarkdown(SharedString),
12498    /// Both single line and multiple lines of plain text documentation.
12499    SingleLineAndMultiLinePlainText {
12500        single_line: SharedString,
12501        plain_text: Option<SharedString>,
12502    },
12503}
12504
12505impl CompletionDocumentation {
12506    #[cfg(any(test, feature = "test-support"))]
12507    pub fn text(&self) -> SharedString {
12508        match self {
12509            CompletionDocumentation::Undocumented => "".into(),
12510            CompletionDocumentation::SingleLine(s) => s.clone(),
12511            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12512            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12513            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12514                single_line.clone()
12515            }
12516        }
12517    }
12518}
12519
12520impl From<lsp::Documentation> for CompletionDocumentation {
12521    fn from(docs: lsp::Documentation) -> Self {
12522        match docs {
12523            lsp::Documentation::String(text) => {
12524                if text.lines().count() <= 1 {
12525                    CompletionDocumentation::SingleLine(text.into())
12526                } else {
12527                    CompletionDocumentation::MultiLinePlainText(text.into())
12528                }
12529            }
12530
12531            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12532                lsp::MarkupKind::PlainText => {
12533                    if value.lines().count() <= 1 {
12534                        CompletionDocumentation::SingleLine(value.into())
12535                    } else {
12536                        CompletionDocumentation::MultiLinePlainText(value.into())
12537                    }
12538                }
12539
12540                lsp::MarkupKind::Markdown => {
12541                    CompletionDocumentation::MultiLineMarkdown(value.into())
12542                }
12543            },
12544        }
12545    }
12546}
12547
12548fn glob_literal_prefix(glob: &Path) -> PathBuf {
12549    glob.components()
12550        .take_while(|component| match component {
12551            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12552            _ => true,
12553        })
12554        .collect()
12555}
12556
12557pub struct SshLspAdapter {
12558    name: LanguageServerName,
12559    binary: LanguageServerBinary,
12560    initialization_options: Option<String>,
12561    code_action_kinds: Option<Vec<CodeActionKind>>,
12562}
12563
12564impl SshLspAdapter {
12565    pub fn new(
12566        name: LanguageServerName,
12567        binary: LanguageServerBinary,
12568        initialization_options: Option<String>,
12569        code_action_kinds: Option<String>,
12570    ) -> Self {
12571        Self {
12572            name,
12573            binary,
12574            initialization_options,
12575            code_action_kinds: code_action_kinds
12576                .as_ref()
12577                .and_then(|c| serde_json::from_str(c).ok()),
12578        }
12579    }
12580}
12581
12582#[async_trait(?Send)]
12583impl LspAdapter for SshLspAdapter {
12584    fn name(&self) -> LanguageServerName {
12585        self.name.clone()
12586    }
12587
12588    async fn initialization_options(
12589        self: Arc<Self>,
12590        _: &Arc<dyn LspAdapterDelegate>,
12591    ) -> Result<Option<serde_json::Value>> {
12592        let Some(options) = &self.initialization_options else {
12593            return Ok(None);
12594        };
12595        let result = serde_json::from_str(options)?;
12596        Ok(result)
12597    }
12598
12599    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12600        self.code_action_kinds.clone()
12601    }
12602
12603    async fn check_if_user_installed(
12604        &self,
12605        _: &dyn LspAdapterDelegate,
12606        _: Option<Toolchain>,
12607        _: &AsyncApp,
12608    ) -> Option<LanguageServerBinary> {
12609        Some(self.binary.clone())
12610    }
12611
12612    async fn cached_server_binary(
12613        &self,
12614        _: PathBuf,
12615        _: &dyn LspAdapterDelegate,
12616    ) -> Option<LanguageServerBinary> {
12617        None
12618    }
12619
12620    async fn fetch_latest_server_version(
12621        &self,
12622        _: &dyn LspAdapterDelegate,
12623        _: &AsyncApp,
12624    ) -> Result<Box<dyn 'static + Send + Any>> {
12625        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12626    }
12627
12628    async fn fetch_server_binary(
12629        &self,
12630        _: Box<dyn 'static + Send + Any>,
12631        _: PathBuf,
12632        _: &dyn LspAdapterDelegate,
12633    ) -> Result<LanguageServerBinary> {
12634        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12635    }
12636}
12637
12638pub fn language_server_settings<'a>(
12639    delegate: &'a dyn LspAdapterDelegate,
12640    language: &LanguageServerName,
12641    cx: &'a App,
12642) -> Option<&'a LspSettings> {
12643    language_server_settings_for(
12644        SettingsLocation {
12645            worktree_id: delegate.worktree_id(),
12646            path: delegate.worktree_root_path(),
12647        },
12648        language,
12649        cx,
12650    )
12651}
12652
12653pub(crate) fn language_server_settings_for<'a>(
12654    location: SettingsLocation<'a>,
12655    language: &LanguageServerName,
12656    cx: &'a App,
12657) -> Option<&'a LspSettings> {
12658    ProjectSettings::get(Some(location), cx).lsp.get(language)
12659}
12660
12661pub struct LocalLspAdapterDelegate {
12662    lsp_store: WeakEntity<LspStore>,
12663    worktree: worktree::Snapshot,
12664    fs: Arc<dyn Fs>,
12665    http_client: Arc<dyn HttpClient>,
12666    language_registry: Arc<LanguageRegistry>,
12667    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12668}
12669
12670impl LocalLspAdapterDelegate {
12671    pub fn new(
12672        language_registry: Arc<LanguageRegistry>,
12673        environment: &Entity<ProjectEnvironment>,
12674        lsp_store: WeakEntity<LspStore>,
12675        worktree: &Entity<Worktree>,
12676        http_client: Arc<dyn HttpClient>,
12677        fs: Arc<dyn Fs>,
12678        cx: &mut App,
12679    ) -> Arc<Self> {
12680        let load_shell_env_task = environment.update(cx, |env, cx| {
12681            env.get_worktree_environment(worktree.clone(), cx)
12682        });
12683
12684        Arc::new(Self {
12685            lsp_store,
12686            worktree: worktree.read(cx).snapshot(),
12687            fs,
12688            http_client,
12689            language_registry,
12690            load_shell_env_task,
12691        })
12692    }
12693
12694    fn from_local_lsp(
12695        local: &LocalLspStore,
12696        worktree: &Entity<Worktree>,
12697        cx: &mut App,
12698    ) -> Arc<Self> {
12699        Self::new(
12700            local.languages.clone(),
12701            &local.environment,
12702            local.weak.clone(),
12703            worktree,
12704            local.http_client.clone(),
12705            local.fs.clone(),
12706            cx,
12707        )
12708    }
12709}
12710
12711#[async_trait]
12712impl LspAdapterDelegate for LocalLspAdapterDelegate {
12713    fn show_notification(&self, message: &str, cx: &mut App) {
12714        self.lsp_store
12715            .update(cx, |_, cx| {
12716                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12717            })
12718            .ok();
12719    }
12720
12721    fn http_client(&self) -> Arc<dyn HttpClient> {
12722        self.http_client.clone()
12723    }
12724
12725    fn worktree_id(&self) -> WorktreeId {
12726        self.worktree.id()
12727    }
12728
12729    fn worktree_root_path(&self) -> &Path {
12730        self.worktree.abs_path().as_ref()
12731    }
12732
12733    async fn shell_env(&self) -> HashMap<String, String> {
12734        let task = self.load_shell_env_task.clone();
12735        task.await.unwrap_or_default()
12736    }
12737
12738    async fn npm_package_installed_version(
12739        &self,
12740        package_name: &str,
12741    ) -> Result<Option<(PathBuf, String)>> {
12742        let local_package_directory = self.worktree_root_path();
12743        let node_modules_directory = local_package_directory.join("node_modules");
12744
12745        if let Some(version) =
12746            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12747        {
12748            return Ok(Some((node_modules_directory, version)));
12749        }
12750        let Some(npm) = self.which("npm".as_ref()).await else {
12751            log::warn!(
12752                "Failed to find npm executable for {:?}",
12753                local_package_directory
12754            );
12755            return Ok(None);
12756        };
12757
12758        let env = self.shell_env().await;
12759        let output = util::command::new_smol_command(&npm)
12760            .args(["root", "-g"])
12761            .envs(env)
12762            .current_dir(local_package_directory)
12763            .output()
12764            .await?;
12765        let global_node_modules =
12766            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12767
12768        if let Some(version) =
12769            read_package_installed_version(global_node_modules.clone(), package_name).await?
12770        {
12771            return Ok(Some((global_node_modules, version)));
12772        }
12773        return Ok(None);
12774    }
12775
12776    #[cfg(not(target_os = "windows"))]
12777    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12778        let worktree_abs_path = self.worktree.abs_path();
12779        let shell_path = self.shell_env().await.get("PATH").cloned();
12780        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12781    }
12782
12783    #[cfg(target_os = "windows")]
12784    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12785        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12786        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12787        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12788        which::which(command).ok()
12789    }
12790
12791    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12792        let working_dir = self.worktree_root_path();
12793        let output = util::command::new_smol_command(&command.path)
12794            .args(command.arguments)
12795            .envs(command.env.clone().unwrap_or_default())
12796            .current_dir(working_dir)
12797            .output()
12798            .await?;
12799
12800        anyhow::ensure!(
12801            output.status.success(),
12802            "{}, stdout: {:?}, stderr: {:?}",
12803            output.status,
12804            String::from_utf8_lossy(&output.stdout),
12805            String::from_utf8_lossy(&output.stderr)
12806        );
12807        Ok(())
12808    }
12809
12810    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
12811        self.language_registry
12812            .update_lsp_binary_status(server_name, status);
12813    }
12814
12815    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
12816        self.language_registry
12817            .all_lsp_adapters()
12818            .into_iter()
12819            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
12820            .collect()
12821    }
12822
12823    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
12824        let dir = self.language_registry.language_server_download_dir(name)?;
12825
12826        if !dir.exists() {
12827            smol::fs::create_dir_all(&dir)
12828                .await
12829                .context("failed to create container directory")
12830                .log_err()?;
12831        }
12832
12833        Some(dir)
12834    }
12835
12836    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
12837        let entry = self
12838            .worktree
12839            .entry_for_path(&path)
12840            .with_context(|| format!("no worktree entry for path {path:?}"))?;
12841        let abs_path = self
12842            .worktree
12843            .absolutize(&entry.path)
12844            .with_context(|| format!("cannot absolutize path {path:?}"))?;
12845
12846        self.fs.load(&abs_path).await
12847    }
12848}
12849
12850async fn populate_labels_for_symbols(
12851    symbols: Vec<CoreSymbol>,
12852    language_registry: &Arc<LanguageRegistry>,
12853    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12854    output: &mut Vec<Symbol>,
12855) {
12856    #[allow(clippy::mutable_key_type)]
12857    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
12858
12859    let mut unknown_paths = BTreeSet::new();
12860    for symbol in symbols {
12861        let language = language_registry
12862            .language_for_file_path(&symbol.path.path)
12863            .await
12864            .ok()
12865            .or_else(|| {
12866                unknown_paths.insert(symbol.path.path.clone());
12867                None
12868            });
12869        symbols_by_language
12870            .entry(language)
12871            .or_default()
12872            .push(symbol);
12873    }
12874
12875    for unknown_path in unknown_paths {
12876        log::info!(
12877            "no language found for symbol path {}",
12878            unknown_path.display()
12879        );
12880    }
12881
12882    let mut label_params = Vec::new();
12883    for (language, mut symbols) in symbols_by_language {
12884        label_params.clear();
12885        label_params.extend(
12886            symbols
12887                .iter_mut()
12888                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
12889        );
12890
12891        let mut labels = Vec::new();
12892        if let Some(language) = language {
12893            let lsp_adapter = lsp_adapter.clone().or_else(|| {
12894                language_registry
12895                    .lsp_adapters(&language.name())
12896                    .first()
12897                    .cloned()
12898            });
12899            if let Some(lsp_adapter) = lsp_adapter {
12900                labels = lsp_adapter
12901                    .labels_for_symbols(&label_params, &language)
12902                    .await
12903                    .log_err()
12904                    .unwrap_or_default();
12905            }
12906        }
12907
12908        for ((symbol, (name, _)), label) in symbols
12909            .into_iter()
12910            .zip(label_params.drain(..))
12911            .zip(labels.into_iter().chain(iter::repeat(None)))
12912        {
12913            output.push(Symbol {
12914                language_server_name: symbol.language_server_name,
12915                source_worktree_id: symbol.source_worktree_id,
12916                source_language_server_id: symbol.source_language_server_id,
12917                path: symbol.path,
12918                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
12919                name,
12920                kind: symbol.kind,
12921                range: symbol.range,
12922                signature: symbol.signature,
12923            });
12924        }
12925    }
12926}
12927
12928fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
12929    match server.capabilities().text_document_sync.as_ref()? {
12930        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
12931            // Server wants didSave but didn't specify includeText.
12932            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
12933            // Server doesn't want didSave at all.
12934            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
12935            // Server provided SaveOptions.
12936            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
12937                Some(save_options.include_text.unwrap_or(false))
12938            }
12939        },
12940        // We do not have any save info. Kind affects didChange only.
12941        lsp::TextDocumentSyncCapability::Kind(_) => None,
12942    }
12943}
12944
12945/// Completion items are displayed in a `UniformList`.
12946/// Usually, those items are single-line strings, but in LSP responses,
12947/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
12948/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
12949/// 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,
12950/// breaking the completions menu presentation.
12951///
12952/// 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.
12953fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
12954    let mut new_text = String::with_capacity(label.text.len());
12955    let mut offset_map = vec![0; label.text.len() + 1];
12956    let mut last_char_was_space = false;
12957    let mut new_idx = 0;
12958    let chars = label.text.char_indices().fuse();
12959    let mut newlines_removed = false;
12960
12961    for (idx, c) in chars {
12962        offset_map[idx] = new_idx;
12963
12964        match c {
12965            '\n' if last_char_was_space => {
12966                newlines_removed = true;
12967            }
12968            '\t' | ' ' if last_char_was_space => {}
12969            '\n' if !last_char_was_space => {
12970                new_text.push(' ');
12971                new_idx += 1;
12972                last_char_was_space = true;
12973                newlines_removed = true;
12974            }
12975            ' ' | '\t' => {
12976                new_text.push(' ');
12977                new_idx += 1;
12978                last_char_was_space = true;
12979            }
12980            _ => {
12981                new_text.push(c);
12982                new_idx += c.len_utf8();
12983                last_char_was_space = false;
12984            }
12985        }
12986    }
12987    offset_map[label.text.len()] = new_idx;
12988
12989    // Only modify the label if newlines were removed.
12990    if !newlines_removed {
12991        return;
12992    }
12993
12994    let last_index = new_idx;
12995    let mut run_ranges_errors = Vec::new();
12996    label.runs.retain_mut(|(range, _)| {
12997        match offset_map.get(range.start) {
12998            Some(&start) => range.start = start,
12999            None => {
13000                run_ranges_errors.push(range.clone());
13001                return false;
13002            }
13003        }
13004
13005        match offset_map.get(range.end) {
13006            Some(&end) => range.end = end,
13007            None => {
13008                run_ranges_errors.push(range.clone());
13009                range.end = last_index;
13010            }
13011        }
13012        true
13013    });
13014    if !run_ranges_errors.is_empty() {
13015        log::error!(
13016            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13017            label.text
13018        );
13019    }
13020
13021    let mut wrong_filter_range = None;
13022    if label.filter_range == (0..label.text.len()) {
13023        label.filter_range = 0..new_text.len();
13024    } else {
13025        let mut original_filter_range = Some(label.filter_range.clone());
13026        match offset_map.get(label.filter_range.start) {
13027            Some(&start) => label.filter_range.start = start,
13028            None => {
13029                wrong_filter_range = original_filter_range.take();
13030                label.filter_range.start = last_index;
13031            }
13032        }
13033
13034        match offset_map.get(label.filter_range.end) {
13035            Some(&end) => label.filter_range.end = end,
13036            None => {
13037                wrong_filter_range = original_filter_range.take();
13038                label.filter_range.end = last_index;
13039            }
13040        }
13041    }
13042    if let Some(wrong_filter_range) = wrong_filter_range {
13043        log::error!(
13044            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13045            label.text
13046        );
13047    }
13048
13049    label.text = new_text;
13050}
13051
13052#[cfg(test)]
13053mod tests {
13054    use language::HighlightId;
13055
13056    use super::*;
13057
13058    #[test]
13059    fn test_glob_literal_prefix() {
13060        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13061        assert_eq!(
13062            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13063            Path::new("node_modules")
13064        );
13065        assert_eq!(
13066            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13067            Path::new("foo")
13068        );
13069        assert_eq!(
13070            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13071            Path::new("foo/bar/baz.js")
13072        );
13073
13074        #[cfg(target_os = "windows")]
13075        {
13076            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13077            assert_eq!(
13078                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13079                Path::new("node_modules")
13080            );
13081            assert_eq!(
13082                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13083                Path::new("foo")
13084            );
13085            assert_eq!(
13086                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13087                Path::new("foo/bar/baz.js")
13088            );
13089        }
13090    }
13091
13092    #[test]
13093    fn test_multi_len_chars_normalization() {
13094        let mut label = CodeLabel {
13095            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13096            runs: vec![(0..6, HighlightId(1))],
13097            filter_range: 0..6,
13098        };
13099        ensure_uniform_list_compatible_label(&mut label);
13100        assert_eq!(
13101            label,
13102            CodeLabel {
13103                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13104                runs: vec![(0..6, HighlightId(1))],
13105                filter_range: 0..6,
13106            }
13107        );
13108    }
13109}