lsp_store.rs

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