lsp_store.rs

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