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