lsp_store.rs

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