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            if !completion_settings.lsp {
 5823                return Task::ready(Ok(Vec::new()));
 5824            }
 5825
 5826            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5827                local
 5828                    .language_servers_for_buffer(buffer, cx)
 5829                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5830                    .filter(|(adapter, _)| {
 5831                        scope
 5832                            .as_ref()
 5833                            .map(|scope| scope.language_allowed(&adapter.name))
 5834                            .unwrap_or(true)
 5835                    })
 5836                    .map(|(_, server)| server.server_id())
 5837                    .collect()
 5838            });
 5839
 5840            let buffer = buffer.clone();
 5841            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5842            let lsp_timeout = if lsp_timeout > 0 {
 5843                Some(Duration::from_millis(lsp_timeout))
 5844            } else {
 5845                None
 5846            };
 5847            cx.spawn(async move |this,  cx| {
 5848                let mut tasks = Vec::with_capacity(server_ids.len());
 5849                this.update(cx, |lsp_store, cx| {
 5850                    for server_id in server_ids {
 5851                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5852                        let lsp_timeout = lsp_timeout
 5853                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5854                        let mut timeout = cx.background_spawn(async move {
 5855                            match lsp_timeout {
 5856                                Some(lsp_timeout) => {
 5857                                    lsp_timeout.await;
 5858                                    true
 5859                                },
 5860                                None => false,
 5861                            }
 5862                        }).fuse();
 5863                        let mut lsp_request = lsp_store.request_lsp(
 5864                            buffer.clone(),
 5865                            LanguageServerToQuery::Other(server_id),
 5866                            GetCompletions {
 5867                                position,
 5868                                context: context.clone(),
 5869                            },
 5870                            cx,
 5871                        ).fuse();
 5872                        let new_task = cx.background_spawn(async move {
 5873                            select_biased! {
 5874                                response = lsp_request => anyhow::Ok(Some(response?)),
 5875                                timeout_happened = timeout => {
 5876                                    if timeout_happened {
 5877                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5878                                        Ok(None)
 5879                                    } else {
 5880                                        let completions = lsp_request.await?;
 5881                                        Ok(Some(completions))
 5882                                    }
 5883                                },
 5884                            }
 5885                        });
 5886                        tasks.push((lsp_adapter, new_task));
 5887                    }
 5888                })?;
 5889
 5890                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5891                    let completion_response = task.await.ok()??;
 5892                    let completions = populate_labels_for_completions(
 5893                            completion_response.completions,
 5894                            language.clone(),
 5895                            lsp_adapter,
 5896                        )
 5897                        .await;
 5898                    Some(CompletionResponse {
 5899                        completions,
 5900                        display_options: CompletionDisplayOptions::default(),
 5901                        is_incomplete: completion_response.is_incomplete,
 5902                    })
 5903                });
 5904
 5905                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5906
 5907                Ok(responses.into_iter().flatten().collect())
 5908            })
 5909        } else {
 5910            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5911        }
 5912    }
 5913
 5914    pub fn resolve_completions(
 5915        &self,
 5916        buffer: Entity<Buffer>,
 5917        completion_indices: Vec<usize>,
 5918        completions: Rc<RefCell<Box<[Completion]>>>,
 5919        cx: &mut Context<Self>,
 5920    ) -> Task<Result<bool>> {
 5921        let client = self.upstream_client();
 5922        let buffer_id = buffer.read(cx).remote_id();
 5923        let buffer_snapshot = buffer.read(cx).snapshot();
 5924
 5925        if !self.check_if_capable_for_proto_request(
 5926            &buffer,
 5927            GetCompletions::can_resolve_completions,
 5928            cx,
 5929        ) {
 5930            return Task::ready(Ok(false));
 5931        }
 5932        cx.spawn(async move |lsp_store, cx| {
 5933            let mut did_resolve = false;
 5934            if let Some((client, project_id)) = client {
 5935                for completion_index in completion_indices {
 5936                    let server_id = {
 5937                        let completion = &completions.borrow()[completion_index];
 5938                        completion.source.server_id()
 5939                    };
 5940                    if let Some(server_id) = server_id {
 5941                        if Self::resolve_completion_remote(
 5942                            project_id,
 5943                            server_id,
 5944                            buffer_id,
 5945                            completions.clone(),
 5946                            completion_index,
 5947                            client.clone(),
 5948                        )
 5949                        .await
 5950                        .log_err()
 5951                        .is_some()
 5952                        {
 5953                            did_resolve = true;
 5954                        }
 5955                    } else {
 5956                        resolve_word_completion(
 5957                            &buffer_snapshot,
 5958                            &mut completions.borrow_mut()[completion_index],
 5959                        );
 5960                    }
 5961                }
 5962            } else {
 5963                for completion_index in completion_indices {
 5964                    let server_id = {
 5965                        let completion = &completions.borrow()[completion_index];
 5966                        completion.source.server_id()
 5967                    };
 5968                    if let Some(server_id) = server_id {
 5969                        let server_and_adapter = lsp_store
 5970                            .read_with(cx, |lsp_store, _| {
 5971                                let server = lsp_store.language_server_for_id(server_id)?;
 5972                                let adapter =
 5973                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5974                                Some((server, adapter))
 5975                            })
 5976                            .ok()
 5977                            .flatten();
 5978                        let Some((server, adapter)) = server_and_adapter else {
 5979                            continue;
 5980                        };
 5981
 5982                        let resolved = Self::resolve_completion_local(
 5983                            server,
 5984                            completions.clone(),
 5985                            completion_index,
 5986                        )
 5987                        .await
 5988                        .log_err()
 5989                        .is_some();
 5990                        if resolved {
 5991                            Self::regenerate_completion_labels(
 5992                                adapter,
 5993                                &buffer_snapshot,
 5994                                completions.clone(),
 5995                                completion_index,
 5996                            )
 5997                            .await
 5998                            .log_err();
 5999                            did_resolve = true;
 6000                        }
 6001                    } else {
 6002                        resolve_word_completion(
 6003                            &buffer_snapshot,
 6004                            &mut completions.borrow_mut()[completion_index],
 6005                        );
 6006                    }
 6007                }
 6008            }
 6009
 6010            Ok(did_resolve)
 6011        })
 6012    }
 6013
 6014    async fn resolve_completion_local(
 6015        server: Arc<lsp::LanguageServer>,
 6016        completions: Rc<RefCell<Box<[Completion]>>>,
 6017        completion_index: usize,
 6018    ) -> Result<()> {
 6019        let server_id = server.server_id();
 6020        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6021            return Ok(());
 6022        }
 6023
 6024        let request = {
 6025            let completion = &completions.borrow()[completion_index];
 6026            match &completion.source {
 6027                CompletionSource::Lsp {
 6028                    lsp_completion,
 6029                    resolved,
 6030                    server_id: completion_server_id,
 6031                    ..
 6032                } => {
 6033                    if *resolved {
 6034                        return Ok(());
 6035                    }
 6036                    anyhow::ensure!(
 6037                        server_id == *completion_server_id,
 6038                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6039                    );
 6040                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6041                }
 6042                CompletionSource::BufferWord { .. }
 6043                | CompletionSource::Dap { .. }
 6044                | CompletionSource::Custom => {
 6045                    return Ok(());
 6046                }
 6047            }
 6048        };
 6049        let resolved_completion = request
 6050            .await
 6051            .into_response()
 6052            .context("resolve completion")?;
 6053
 6054        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6055        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6056
 6057        let mut completions = completions.borrow_mut();
 6058        let completion = &mut completions[completion_index];
 6059        if let CompletionSource::Lsp {
 6060            lsp_completion,
 6061            resolved,
 6062            server_id: completion_server_id,
 6063            ..
 6064        } = &mut completion.source
 6065        {
 6066            if *resolved {
 6067                return Ok(());
 6068            }
 6069            anyhow::ensure!(
 6070                server_id == *completion_server_id,
 6071                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6072            );
 6073            *lsp_completion = Box::new(resolved_completion);
 6074            *resolved = true;
 6075        }
 6076        Ok(())
 6077    }
 6078
 6079    async fn regenerate_completion_labels(
 6080        adapter: Arc<CachedLspAdapter>,
 6081        snapshot: &BufferSnapshot,
 6082        completions: Rc<RefCell<Box<[Completion]>>>,
 6083        completion_index: usize,
 6084    ) -> Result<()> {
 6085        let completion_item = completions.borrow()[completion_index]
 6086            .source
 6087            .lsp_completion(true)
 6088            .map(Cow::into_owned);
 6089        if let Some(lsp_documentation) = completion_item
 6090            .as_ref()
 6091            .and_then(|completion_item| completion_item.documentation.clone())
 6092        {
 6093            let mut completions = completions.borrow_mut();
 6094            let completion = &mut completions[completion_index];
 6095            completion.documentation = Some(lsp_documentation.into());
 6096        } else {
 6097            let mut completions = completions.borrow_mut();
 6098            let completion = &mut completions[completion_index];
 6099            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6100        }
 6101
 6102        let mut new_label = match completion_item {
 6103            Some(completion_item) => {
 6104                // 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
 6105                // So we have to update the label here anyway...
 6106                let language = snapshot.language();
 6107                match language {
 6108                    Some(language) => {
 6109                        adapter
 6110                            .labels_for_completions(
 6111                                std::slice::from_ref(&completion_item),
 6112                                language,
 6113                            )
 6114                            .await?
 6115                    }
 6116                    None => Vec::new(),
 6117                }
 6118                .pop()
 6119                .flatten()
 6120                .unwrap_or_else(|| {
 6121                    CodeLabel::fallback_for_completion(
 6122                        &completion_item,
 6123                        language.map(|language| language.as_ref()),
 6124                    )
 6125                })
 6126            }
 6127            None => CodeLabel::plain(
 6128                completions.borrow()[completion_index].new_text.clone(),
 6129                None,
 6130            ),
 6131        };
 6132        ensure_uniform_list_compatible_label(&mut new_label);
 6133
 6134        let mut completions = completions.borrow_mut();
 6135        let completion = &mut completions[completion_index];
 6136        if completion.label.filter_text() == new_label.filter_text() {
 6137            completion.label = new_label;
 6138        } else {
 6139            log::error!(
 6140                "Resolved completion changed display label from {} to {}. \
 6141                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6142                completion.label.text(),
 6143                new_label.text(),
 6144                completion.label.filter_text(),
 6145                new_label.filter_text()
 6146            );
 6147        }
 6148
 6149        Ok(())
 6150    }
 6151
 6152    async fn resolve_completion_remote(
 6153        project_id: u64,
 6154        server_id: LanguageServerId,
 6155        buffer_id: BufferId,
 6156        completions: Rc<RefCell<Box<[Completion]>>>,
 6157        completion_index: usize,
 6158        client: AnyProtoClient,
 6159    ) -> Result<()> {
 6160        let lsp_completion = {
 6161            let completion = &completions.borrow()[completion_index];
 6162            match &completion.source {
 6163                CompletionSource::Lsp {
 6164                    lsp_completion,
 6165                    resolved,
 6166                    server_id: completion_server_id,
 6167                    ..
 6168                } => {
 6169                    anyhow::ensure!(
 6170                        server_id == *completion_server_id,
 6171                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6172                    );
 6173                    if *resolved {
 6174                        return Ok(());
 6175                    }
 6176                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6177                }
 6178                CompletionSource::Custom
 6179                | CompletionSource::Dap { .. }
 6180                | CompletionSource::BufferWord { .. } => {
 6181                    return Ok(());
 6182                }
 6183            }
 6184        };
 6185        let request = proto::ResolveCompletionDocumentation {
 6186            project_id,
 6187            language_server_id: server_id.0 as u64,
 6188            lsp_completion,
 6189            buffer_id: buffer_id.into(),
 6190        };
 6191
 6192        let response = client
 6193            .request(request)
 6194            .await
 6195            .context("completion documentation resolve proto request")?;
 6196        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6197
 6198        let documentation = if response.documentation.is_empty() {
 6199            CompletionDocumentation::Undocumented
 6200        } else if response.documentation_is_markdown {
 6201            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6202        } else if response.documentation.lines().count() <= 1 {
 6203            CompletionDocumentation::SingleLine(response.documentation.into())
 6204        } else {
 6205            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6206        };
 6207
 6208        let mut completions = completions.borrow_mut();
 6209        let completion = &mut completions[completion_index];
 6210        completion.documentation = Some(documentation);
 6211        if let CompletionSource::Lsp {
 6212            insert_range,
 6213            lsp_completion,
 6214            resolved,
 6215            server_id: completion_server_id,
 6216            lsp_defaults: _,
 6217        } = &mut completion.source
 6218        {
 6219            let completion_insert_range = response
 6220                .old_insert_start
 6221                .and_then(deserialize_anchor)
 6222                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6223            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6224
 6225            if *resolved {
 6226                return Ok(());
 6227            }
 6228            anyhow::ensure!(
 6229                server_id == *completion_server_id,
 6230                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6231            );
 6232            *lsp_completion = Box::new(resolved_lsp_completion);
 6233            *resolved = true;
 6234        }
 6235
 6236        let replace_range = response
 6237            .old_replace_start
 6238            .and_then(deserialize_anchor)
 6239            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6240        if let Some((old_replace_start, old_replace_end)) = replace_range
 6241            && !response.new_text.is_empty()
 6242        {
 6243            completion.new_text = response.new_text;
 6244            completion.replace_range = old_replace_start..old_replace_end;
 6245        }
 6246
 6247        Ok(())
 6248    }
 6249
 6250    pub fn apply_additional_edits_for_completion(
 6251        &self,
 6252        buffer_handle: Entity<Buffer>,
 6253        completions: Rc<RefCell<Box<[Completion]>>>,
 6254        completion_index: usize,
 6255        push_to_history: bool,
 6256        cx: &mut Context<Self>,
 6257    ) -> Task<Result<Option<Transaction>>> {
 6258        if let Some((client, project_id)) = self.upstream_client() {
 6259            let buffer = buffer_handle.read(cx);
 6260            let buffer_id = buffer.remote_id();
 6261            cx.spawn(async move |_, cx| {
 6262                let request = {
 6263                    let completion = completions.borrow()[completion_index].clone();
 6264                    proto::ApplyCompletionAdditionalEdits {
 6265                        project_id,
 6266                        buffer_id: buffer_id.into(),
 6267                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6268                            replace_range: completion.replace_range,
 6269                            new_text: completion.new_text,
 6270                            source: completion.source,
 6271                        })),
 6272                    }
 6273                };
 6274
 6275                if let Some(transaction) = client.request(request).await?.transaction {
 6276                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6277                    buffer_handle
 6278                        .update(cx, |buffer, _| {
 6279                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6280                        })?
 6281                        .await?;
 6282                    if push_to_history {
 6283                        buffer_handle.update(cx, |buffer, _| {
 6284                            buffer.push_transaction(transaction.clone(), Instant::now());
 6285                            buffer.finalize_last_transaction();
 6286                        })?;
 6287                    }
 6288                    Ok(Some(transaction))
 6289                } else {
 6290                    Ok(None)
 6291                }
 6292            })
 6293        } else {
 6294            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6295                let completion = &completions.borrow()[completion_index];
 6296                let server_id = completion.source.server_id()?;
 6297                Some(
 6298                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6299                        .1
 6300                        .clone(),
 6301                )
 6302            }) else {
 6303                return Task::ready(Ok(None));
 6304            };
 6305
 6306            cx.spawn(async move |this, cx| {
 6307                Self::resolve_completion_local(
 6308                    server.clone(),
 6309                    completions.clone(),
 6310                    completion_index,
 6311                )
 6312                .await
 6313                .context("resolving completion")?;
 6314                let completion = completions.borrow()[completion_index].clone();
 6315                let additional_text_edits = completion
 6316                    .source
 6317                    .lsp_completion(true)
 6318                    .as_ref()
 6319                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6320                if let Some(edits) = additional_text_edits {
 6321                    let edits = this
 6322                        .update(cx, |this, cx| {
 6323                            this.as_local_mut().unwrap().edits_from_lsp(
 6324                                &buffer_handle,
 6325                                edits,
 6326                                server.server_id(),
 6327                                None,
 6328                                cx,
 6329                            )
 6330                        })?
 6331                        .await?;
 6332
 6333                    buffer_handle.update(cx, |buffer, cx| {
 6334                        buffer.finalize_last_transaction();
 6335                        buffer.start_transaction();
 6336
 6337                        for (range, text) in edits {
 6338                            let primary = &completion.replace_range;
 6339
 6340                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6341                            // and the primary completion is just an insertion (empty range), then this is likely
 6342                            // an auto-import scenario and should not be considered overlapping
 6343                            // https://github.com/zed-industries/zed/issues/26136
 6344                            let is_file_start_auto_import = {
 6345                                let snapshot = buffer.snapshot();
 6346                                let primary_start_point = primary.start.to_point(&snapshot);
 6347                                let range_start_point = range.start.to_point(&snapshot);
 6348
 6349                                let result = primary_start_point.row == 0
 6350                                    && primary_start_point.column == 0
 6351                                    && range_start_point.row == 0
 6352                                    && range_start_point.column == 0;
 6353
 6354                                result
 6355                            };
 6356
 6357                            let has_overlap = if is_file_start_auto_import {
 6358                                false
 6359                            } else {
 6360                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6361                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6362                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6363                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6364                                let result = start_within || end_within;
 6365                                result
 6366                            };
 6367
 6368                            //Skip additional edits which overlap with the primary completion edit
 6369                            //https://github.com/zed-industries/zed/pull/1871
 6370                            if !has_overlap {
 6371                                buffer.edit([(range, text)], None, cx);
 6372                            }
 6373                        }
 6374
 6375                        let transaction = if buffer.end_transaction(cx).is_some() {
 6376                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6377                            if !push_to_history {
 6378                                buffer.forget_transaction(transaction.id);
 6379                            }
 6380                            Some(transaction)
 6381                        } else {
 6382                            None
 6383                        };
 6384                        Ok(transaction)
 6385                    })?
 6386                } else {
 6387                    Ok(None)
 6388                }
 6389            })
 6390        }
 6391    }
 6392
 6393    pub fn pull_diagnostics(
 6394        &mut self,
 6395        buffer: Entity<Buffer>,
 6396        cx: &mut Context<Self>,
 6397    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6398        let buffer_id = buffer.read(cx).remote_id();
 6399
 6400        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6401            let request = GetDocumentDiagnostics {
 6402                previous_result_id: None,
 6403            };
 6404            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6405                return Task::ready(Ok(None));
 6406            }
 6407            let request_task = client.request_lsp(
 6408                upstream_project_id,
 6409                LSP_REQUEST_TIMEOUT,
 6410                cx.background_executor().clone(),
 6411                request.to_proto(upstream_project_id, buffer.read(cx)),
 6412            );
 6413            cx.background_spawn(async move {
 6414                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6415                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6416                // Do not attempt to further process the dummy responses here.
 6417                let _response = request_task.await?;
 6418                Ok(None)
 6419            })
 6420        } else {
 6421            let server_ids = buffer.update(cx, |buffer, cx| {
 6422                self.language_servers_for_local_buffer(buffer, cx)
 6423                    .map(|(_, server)| server.server_id())
 6424                    .collect::<Vec<_>>()
 6425            });
 6426            let pull_diagnostics = server_ids
 6427                .into_iter()
 6428                .map(|server_id| {
 6429                    let result_id = self.result_id(server_id, buffer_id, cx);
 6430                    self.request_lsp(
 6431                        buffer.clone(),
 6432                        LanguageServerToQuery::Other(server_id),
 6433                        GetDocumentDiagnostics {
 6434                            previous_result_id: result_id,
 6435                        },
 6436                        cx,
 6437                    )
 6438                })
 6439                .collect::<Vec<_>>();
 6440
 6441            cx.background_spawn(async move {
 6442                let mut responses = Vec::new();
 6443                for diagnostics in join_all(pull_diagnostics).await {
 6444                    responses.extend(diagnostics?);
 6445                }
 6446                Ok(Some(responses))
 6447            })
 6448        }
 6449    }
 6450
 6451    pub fn inlay_hints(
 6452        &mut self,
 6453        buffer: Entity<Buffer>,
 6454        range: Range<Anchor>,
 6455        cx: &mut Context<Self>,
 6456    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6457        let range_start = range.start;
 6458        let range_end = range.end;
 6459        let buffer_id = buffer.read(cx).remote_id().into();
 6460        let request = InlayHints { range };
 6461
 6462        if let Some((client, project_id)) = self.upstream_client() {
 6463            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6464                return Task::ready(Ok(Vec::new()));
 6465            }
 6466            let proto_request = proto::InlayHints {
 6467                project_id,
 6468                buffer_id,
 6469                start: Some(serialize_anchor(&range_start)),
 6470                end: Some(serialize_anchor(&range_end)),
 6471                version: serialize_version(&buffer.read(cx).version()),
 6472            };
 6473            cx.spawn(async move |project, cx| {
 6474                let response = client
 6475                    .request(proto_request)
 6476                    .await
 6477                    .context("inlay hints proto request")?;
 6478                LspCommand::response_from_proto(
 6479                    request,
 6480                    response,
 6481                    project.upgrade().context("No project")?,
 6482                    buffer.clone(),
 6483                    cx.clone(),
 6484                )
 6485                .await
 6486                .context("inlay hints proto response conversion")
 6487            })
 6488        } else {
 6489            let lsp_request_task = self.request_lsp(
 6490                buffer.clone(),
 6491                LanguageServerToQuery::FirstCapable,
 6492                request,
 6493                cx,
 6494            );
 6495            cx.spawn(async move |_, cx| {
 6496                buffer
 6497                    .update(cx, |buffer, _| {
 6498                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6499                    })?
 6500                    .await
 6501                    .context("waiting for inlay hint request range edits")?;
 6502                lsp_request_task.await.context("inlay hints LSP request")
 6503            })
 6504        }
 6505    }
 6506
 6507    pub fn pull_diagnostics_for_buffer(
 6508        &mut self,
 6509        buffer: Entity<Buffer>,
 6510        cx: &mut Context<Self>,
 6511    ) -> Task<anyhow::Result<()>> {
 6512        let diagnostics = self.pull_diagnostics(buffer, cx);
 6513        cx.spawn(async move |lsp_store, cx| {
 6514            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6515                return Ok(());
 6516            };
 6517            lsp_store.update(cx, |lsp_store, cx| {
 6518                if lsp_store.as_local().is_none() {
 6519                    return;
 6520                }
 6521
 6522                let mut unchanged_buffers = HashSet::default();
 6523                let mut changed_buffers = HashSet::default();
 6524                let server_diagnostics_updates = diagnostics
 6525                    .into_iter()
 6526                    .filter_map(|diagnostics_set| match diagnostics_set {
 6527                        LspPullDiagnostics::Response {
 6528                            server_id,
 6529                            uri,
 6530                            diagnostics,
 6531                        } => Some((server_id, uri, diagnostics)),
 6532                        LspPullDiagnostics::Default => None,
 6533                    })
 6534                    .fold(
 6535                        HashMap::default(),
 6536                        |mut acc, (server_id, uri, diagnostics)| {
 6537                            let (result_id, diagnostics) = match diagnostics {
 6538                                PulledDiagnostics::Unchanged { result_id } => {
 6539                                    unchanged_buffers.insert(uri.clone());
 6540                                    (Some(result_id), Vec::new())
 6541                                }
 6542                                PulledDiagnostics::Changed {
 6543                                    result_id,
 6544                                    diagnostics,
 6545                                } => {
 6546                                    changed_buffers.insert(uri.clone());
 6547                                    (result_id, diagnostics)
 6548                                }
 6549                            };
 6550                            let disk_based_sources = Cow::Owned(
 6551                                lsp_store
 6552                                    .language_server_adapter_for_id(server_id)
 6553                                    .as_ref()
 6554                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6555                                    .unwrap_or(&[])
 6556                                    .to_vec(),
 6557                            );
 6558                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6559                                DocumentDiagnosticsUpdate {
 6560                                    server_id,
 6561                                    diagnostics: lsp::PublishDiagnosticsParams {
 6562                                        uri,
 6563                                        diagnostics,
 6564                                        version: None,
 6565                                    },
 6566                                    result_id,
 6567                                    disk_based_sources,
 6568                                },
 6569                            );
 6570                            acc
 6571                        },
 6572                    );
 6573
 6574                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6575                    lsp_store
 6576                        .merge_lsp_diagnostics(
 6577                            DiagnosticSourceKind::Pulled,
 6578                            diagnostic_updates,
 6579                            |buffer, old_diagnostic, cx| {
 6580                                File::from_dyn(buffer.file())
 6581                                    .and_then(|file| {
 6582                                        let abs_path = file.as_local()?.abs_path(cx);
 6583                                        lsp::Uri::from_file_path(abs_path).ok()
 6584                                    })
 6585                                    .is_none_or(|buffer_uri| {
 6586                                        unchanged_buffers.contains(&buffer_uri)
 6587                                            || match old_diagnostic.source_kind {
 6588                                                DiagnosticSourceKind::Pulled => {
 6589                                                    !changed_buffers.contains(&buffer_uri)
 6590                                                }
 6591                                                DiagnosticSourceKind::Other
 6592                                                | DiagnosticSourceKind::Pushed => true,
 6593                                            }
 6594                                    })
 6595                            },
 6596                            cx,
 6597                        )
 6598                        .log_err();
 6599                }
 6600            })
 6601        })
 6602    }
 6603
 6604    pub fn document_colors(
 6605        &mut self,
 6606        fetch_strategy: LspFetchStrategy,
 6607        buffer: Entity<Buffer>,
 6608        cx: &mut Context<Self>,
 6609    ) -> Option<DocumentColorTask> {
 6610        let version_queried_for = buffer.read(cx).version();
 6611        let buffer_id = buffer.read(cx).remote_id();
 6612
 6613        match fetch_strategy {
 6614            LspFetchStrategy::IgnoreCache => {}
 6615            LspFetchStrategy::UseCache {
 6616                known_cache_version,
 6617            } => {
 6618                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6619                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6620                {
 6621                    let has_different_servers = self.as_local().is_some_and(|local| {
 6622                        local
 6623                            .buffers_opened_in_servers
 6624                            .get(&buffer_id)
 6625                            .cloned()
 6626                            .unwrap_or_default()
 6627                            != cached_data.colors.keys().copied().collect()
 6628                    });
 6629                    if !has_different_servers {
 6630                        if Some(cached_data.cache_version) == known_cache_version {
 6631                            return None;
 6632                        } else {
 6633                            return Some(
 6634                                Task::ready(Ok(DocumentColors {
 6635                                    colors: cached_data
 6636                                        .colors
 6637                                        .values()
 6638                                        .flatten()
 6639                                        .cloned()
 6640                                        .collect(),
 6641                                    cache_version: Some(cached_data.cache_version),
 6642                                }))
 6643                                .shared(),
 6644                            );
 6645                        }
 6646                    }
 6647                }
 6648            }
 6649        }
 6650
 6651        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6652        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6653            && !version_queried_for.changed_since(updating_for)
 6654        {
 6655            return Some(running_update.clone());
 6656        }
 6657        let query_version_queried_for = version_queried_for.clone();
 6658        let new_task = cx
 6659            .spawn(async move |lsp_store, cx| {
 6660                cx.background_executor()
 6661                    .timer(Duration::from_millis(30))
 6662                    .await;
 6663                let fetched_colors = lsp_store
 6664                    .update(cx, |lsp_store, cx| {
 6665                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6666                    })?
 6667                    .await
 6668                    .context("fetching document colors")
 6669                    .map_err(Arc::new);
 6670                let fetched_colors = match fetched_colors {
 6671                    Ok(fetched_colors) => {
 6672                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6673                            && Some(true)
 6674                                == buffer
 6675                                    .update(cx, |buffer, _| {
 6676                                        buffer.version() != query_version_queried_for
 6677                                    })
 6678                                    .ok()
 6679                        {
 6680                            return Ok(DocumentColors::default());
 6681                        }
 6682                        fetched_colors
 6683                    }
 6684                    Err(e) => {
 6685                        lsp_store
 6686                            .update(cx, |lsp_store, _| {
 6687                                lsp_store
 6688                                    .lsp_document_colors
 6689                                    .entry(buffer_id)
 6690                                    .or_default()
 6691                                    .colors_update = None;
 6692                            })
 6693                            .ok();
 6694                        return Err(e);
 6695                    }
 6696                };
 6697
 6698                lsp_store
 6699                    .update(cx, |lsp_store, _| {
 6700                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6701
 6702                        if let Some(fetched_colors) = fetched_colors {
 6703                            if lsp_data.colors_for_version == query_version_queried_for {
 6704                                lsp_data.colors.extend(fetched_colors);
 6705                                lsp_data.cache_version += 1;
 6706                            } else if !lsp_data
 6707                                .colors_for_version
 6708                                .changed_since(&query_version_queried_for)
 6709                            {
 6710                                lsp_data.colors_for_version = query_version_queried_for;
 6711                                lsp_data.colors = fetched_colors;
 6712                                lsp_data.cache_version += 1;
 6713                            }
 6714                        }
 6715                        lsp_data.colors_update = None;
 6716                        let colors = lsp_data
 6717                            .colors
 6718                            .values()
 6719                            .flatten()
 6720                            .cloned()
 6721                            .collect::<HashSet<_>>();
 6722                        DocumentColors {
 6723                            colors,
 6724                            cache_version: Some(lsp_data.cache_version),
 6725                        }
 6726                    })
 6727                    .map_err(Arc::new)
 6728            })
 6729            .shared();
 6730        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6731        Some(new_task)
 6732    }
 6733
 6734    fn fetch_document_colors_for_buffer(
 6735        &mut self,
 6736        buffer: &Entity<Buffer>,
 6737        cx: &mut Context<Self>,
 6738    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6739        if let Some((client, project_id)) = self.upstream_client() {
 6740            let request = GetDocumentColor {};
 6741            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6742                return Task::ready(Ok(None));
 6743            }
 6744
 6745            let request_task = client.request_lsp(
 6746                project_id,
 6747                LSP_REQUEST_TIMEOUT,
 6748                cx.background_executor().clone(),
 6749                request.to_proto(project_id, buffer.read(cx)),
 6750            );
 6751            let buffer = buffer.clone();
 6752            cx.spawn(async move |lsp_store, cx| {
 6753                let Some(project) = lsp_store.upgrade() else {
 6754                    return Ok(None);
 6755                };
 6756                let colors = join_all(
 6757                    request_task
 6758                        .await
 6759                        .log_err()
 6760                        .flatten()
 6761                        .map(|response| response.payload)
 6762                        .unwrap_or_default()
 6763                        .into_iter()
 6764                        .map(|color_response| {
 6765                            let response = request.response_from_proto(
 6766                                color_response.response,
 6767                                project.clone(),
 6768                                buffer.clone(),
 6769                                cx.clone(),
 6770                            );
 6771                            async move {
 6772                                (
 6773                                    LanguageServerId::from_proto(color_response.server_id),
 6774                                    response.await.log_err().unwrap_or_default(),
 6775                                )
 6776                            }
 6777                        }),
 6778                )
 6779                .await
 6780                .into_iter()
 6781                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6782                    acc.entry(server_id)
 6783                        .or_insert_with(HashSet::default)
 6784                        .extend(colors);
 6785                    acc
 6786                });
 6787                Ok(Some(colors))
 6788            })
 6789        } else {
 6790            let document_colors_task =
 6791                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6792            cx.background_spawn(async move {
 6793                Ok(Some(
 6794                    document_colors_task
 6795                        .await
 6796                        .into_iter()
 6797                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6798                            acc.entry(server_id)
 6799                                .or_insert_with(HashSet::default)
 6800                                .extend(colors);
 6801                            acc
 6802                        })
 6803                        .into_iter()
 6804                        .collect(),
 6805                ))
 6806            })
 6807        }
 6808    }
 6809
 6810    pub fn signature_help<T: ToPointUtf16>(
 6811        &mut self,
 6812        buffer: &Entity<Buffer>,
 6813        position: T,
 6814        cx: &mut Context<Self>,
 6815    ) -> Task<Option<Vec<SignatureHelp>>> {
 6816        let position = position.to_point_utf16(buffer.read(cx));
 6817
 6818        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6819            let request = GetSignatureHelp { position };
 6820            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6821                return Task::ready(None);
 6822            }
 6823            let request_task = client.request_lsp(
 6824                upstream_project_id,
 6825                LSP_REQUEST_TIMEOUT,
 6826                cx.background_executor().clone(),
 6827                request.to_proto(upstream_project_id, buffer.read(cx)),
 6828            );
 6829            let buffer = buffer.clone();
 6830            cx.spawn(async move |weak_project, cx| {
 6831                let project = weak_project.upgrade()?;
 6832                let signatures = join_all(
 6833                    request_task
 6834                        .await
 6835                        .log_err()
 6836                        .flatten()
 6837                        .map(|response| response.payload)
 6838                        .unwrap_or_default()
 6839                        .into_iter()
 6840                        .map(|response| {
 6841                            let response = GetSignatureHelp { position }.response_from_proto(
 6842                                response.response,
 6843                                project.clone(),
 6844                                buffer.clone(),
 6845                                cx.clone(),
 6846                            );
 6847                            async move { response.await.log_err().flatten() }
 6848                        }),
 6849                )
 6850                .await
 6851                .into_iter()
 6852                .flatten()
 6853                .collect();
 6854                Some(signatures)
 6855            })
 6856        } else {
 6857            let all_actions_task = self.request_multiple_lsp_locally(
 6858                buffer,
 6859                Some(position),
 6860                GetSignatureHelp { position },
 6861                cx,
 6862            );
 6863            cx.background_spawn(async move {
 6864                Some(
 6865                    all_actions_task
 6866                        .await
 6867                        .into_iter()
 6868                        .flat_map(|(_, actions)| actions)
 6869                        .collect::<Vec<_>>(),
 6870                )
 6871            })
 6872        }
 6873    }
 6874
 6875    pub fn hover(
 6876        &mut self,
 6877        buffer: &Entity<Buffer>,
 6878        position: PointUtf16,
 6879        cx: &mut Context<Self>,
 6880    ) -> Task<Option<Vec<Hover>>> {
 6881        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6882            let request = GetHover { position };
 6883            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6884                return Task::ready(None);
 6885            }
 6886            let request_task = client.request_lsp(
 6887                upstream_project_id,
 6888                LSP_REQUEST_TIMEOUT,
 6889                cx.background_executor().clone(),
 6890                request.to_proto(upstream_project_id, buffer.read(cx)),
 6891            );
 6892            let buffer = buffer.clone();
 6893            cx.spawn(async move |weak_project, cx| {
 6894                let project = weak_project.upgrade()?;
 6895                let hovers = join_all(
 6896                    request_task
 6897                        .await
 6898                        .log_err()
 6899                        .flatten()
 6900                        .map(|response| response.payload)
 6901                        .unwrap_or_default()
 6902                        .into_iter()
 6903                        .map(|response| {
 6904                            let response = GetHover { position }.response_from_proto(
 6905                                response.response,
 6906                                project.clone(),
 6907                                buffer.clone(),
 6908                                cx.clone(),
 6909                            );
 6910                            async move {
 6911                                response
 6912                                    .await
 6913                                    .log_err()
 6914                                    .flatten()
 6915                                    .and_then(remove_empty_hover_blocks)
 6916                            }
 6917                        }),
 6918                )
 6919                .await
 6920                .into_iter()
 6921                .flatten()
 6922                .collect();
 6923                Some(hovers)
 6924            })
 6925        } else {
 6926            let all_actions_task = self.request_multiple_lsp_locally(
 6927                buffer,
 6928                Some(position),
 6929                GetHover { position },
 6930                cx,
 6931            );
 6932            cx.background_spawn(async move {
 6933                Some(
 6934                    all_actions_task
 6935                        .await
 6936                        .into_iter()
 6937                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6938                        .collect::<Vec<Hover>>(),
 6939                )
 6940            })
 6941        }
 6942    }
 6943
 6944    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6945        let language_registry = self.languages.clone();
 6946
 6947        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6948            let request = upstream_client.request(proto::GetProjectSymbols {
 6949                project_id: *project_id,
 6950                query: query.to_string(),
 6951            });
 6952            cx.foreground_executor().spawn(async move {
 6953                let response = request.await?;
 6954                let mut symbols = Vec::new();
 6955                let core_symbols = response
 6956                    .symbols
 6957                    .into_iter()
 6958                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6959                    .collect::<Vec<_>>();
 6960                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6961                    .await;
 6962                Ok(symbols)
 6963            })
 6964        } else if let Some(local) = self.as_local() {
 6965            struct WorkspaceSymbolsResult {
 6966                server_id: LanguageServerId,
 6967                lsp_adapter: Arc<CachedLspAdapter>,
 6968                worktree: WeakEntity<Worktree>,
 6969                worktree_abs_path: Arc<Path>,
 6970                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6971            }
 6972
 6973            let mut requests = Vec::new();
 6974            let mut requested_servers = BTreeSet::new();
 6975            for (seed, state) in local.language_server_ids.iter() {
 6976                let Some(worktree_handle) = self
 6977                    .worktree_store
 6978                    .read(cx)
 6979                    .worktree_for_id(seed.worktree_id, cx)
 6980                else {
 6981                    continue;
 6982                };
 6983                let worktree = worktree_handle.read(cx);
 6984                if !worktree.is_visible() {
 6985                    continue;
 6986                }
 6987
 6988                if !requested_servers.insert(state.id) {
 6989                    continue;
 6990                }
 6991
 6992                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 6993                    Some(LanguageServerState::Running {
 6994                        adapter, server, ..
 6995                    }) => (adapter.clone(), server),
 6996
 6997                    _ => continue,
 6998                };
 6999                let supports_workspace_symbol_request =
 7000                    match server.capabilities().workspace_symbol_provider {
 7001                        Some(OneOf::Left(supported)) => supported,
 7002                        Some(OneOf::Right(_)) => true,
 7003                        None => false,
 7004                    };
 7005                if !supports_workspace_symbol_request {
 7006                    continue;
 7007                }
 7008                let worktree_abs_path = worktree.abs_path().clone();
 7009                let worktree_handle = worktree_handle.clone();
 7010                let server_id = server.server_id();
 7011                requests.push(
 7012                        server
 7013                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7014                                lsp::WorkspaceSymbolParams {
 7015                                    query: query.to_string(),
 7016                                    ..Default::default()
 7017                                },
 7018                            )
 7019                            .map(move |response| {
 7020                                let lsp_symbols = response.into_response()
 7021                                    .context("workspace symbols request")
 7022                                    .log_err()
 7023                                    .flatten()
 7024                                    .map(|symbol_response| match symbol_response {
 7025                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7026                                            flat_responses.into_iter().map(|lsp_symbol| {
 7027                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7028                                            }).collect::<Vec<_>>()
 7029                                        }
 7030                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7031                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7032                                                let location = match lsp_symbol.location {
 7033                                                    OneOf::Left(location) => location,
 7034                                                    OneOf::Right(_) => {
 7035                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7036                                                        return None
 7037                                                    }
 7038                                                };
 7039                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7040                                            }).collect::<Vec<_>>()
 7041                                        }
 7042                                    }).unwrap_or_default();
 7043
 7044                                WorkspaceSymbolsResult {
 7045                                    server_id,
 7046                                    lsp_adapter,
 7047                                    worktree: worktree_handle.downgrade(),
 7048                                    worktree_abs_path,
 7049                                    lsp_symbols,
 7050                                }
 7051                            }),
 7052                    );
 7053            }
 7054
 7055            cx.spawn(async move |this, cx| {
 7056                let responses = futures::future::join_all(requests).await;
 7057                let this = match this.upgrade() {
 7058                    Some(this) => this,
 7059                    None => return Ok(Vec::new()),
 7060                };
 7061
 7062                let mut symbols = Vec::new();
 7063                for result in responses {
 7064                    let core_symbols = this.update(cx, |this, cx| {
 7065                        result
 7066                            .lsp_symbols
 7067                            .into_iter()
 7068                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7069                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7070                                let source_worktree = result.worktree.upgrade()?;
 7071                                let source_worktree_id = source_worktree.read(cx).id();
 7072
 7073                                let path;
 7074                                let worktree;
 7075                                if let Some((tree, rel_path)) =
 7076                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7077                                {
 7078                                    worktree = tree;
 7079                                    path = rel_path;
 7080                                } else {
 7081                                    worktree = source_worktree;
 7082                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7083                                }
 7084
 7085                                let worktree_id = worktree.read(cx).id();
 7086                                let project_path = ProjectPath {
 7087                                    worktree_id,
 7088                                    path: path.into(),
 7089                                };
 7090                                let signature = this.symbol_signature(&project_path);
 7091                                Some(CoreSymbol {
 7092                                    source_language_server_id: result.server_id,
 7093                                    language_server_name: result.lsp_adapter.name.clone(),
 7094                                    source_worktree_id,
 7095                                    path: project_path,
 7096                                    kind: symbol_kind,
 7097                                    name: symbol_name,
 7098                                    range: range_from_lsp(symbol_location.range),
 7099                                    signature,
 7100                                })
 7101                            })
 7102                            .collect()
 7103                    })?;
 7104
 7105                    populate_labels_for_symbols(
 7106                        core_symbols,
 7107                        &language_registry,
 7108                        Some(result.lsp_adapter),
 7109                        &mut symbols,
 7110                    )
 7111                    .await;
 7112                }
 7113
 7114                Ok(symbols)
 7115            })
 7116        } else {
 7117            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7118        }
 7119    }
 7120
 7121    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7122        let mut summary = DiagnosticSummary::default();
 7123        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7124            summary.error_count += path_summary.error_count;
 7125            summary.warning_count += path_summary.warning_count;
 7126        }
 7127        summary
 7128    }
 7129
 7130    /// Returns the diagnostic summary for a specific project path.
 7131    pub fn diagnostic_summary_for_path(
 7132        &self,
 7133        project_path: &ProjectPath,
 7134        _: &App,
 7135    ) -> DiagnosticSummary {
 7136        if let Some(summaries) = self
 7137            .diagnostic_summaries
 7138            .get(&project_path.worktree_id)
 7139            .and_then(|map| map.get(&project_path.path))
 7140        {
 7141            let (error_count, warning_count) = summaries.iter().fold(
 7142                (0, 0),
 7143                |(error_count, warning_count), (_language_server_id, summary)| {
 7144                    (
 7145                        error_count + summary.error_count,
 7146                        warning_count + summary.warning_count,
 7147                    )
 7148                },
 7149            );
 7150
 7151            DiagnosticSummary {
 7152                error_count,
 7153                warning_count,
 7154            }
 7155        } else {
 7156            DiagnosticSummary::default()
 7157        }
 7158    }
 7159
 7160    pub fn diagnostic_summaries<'a>(
 7161        &'a self,
 7162        include_ignored: bool,
 7163        cx: &'a App,
 7164    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7165        self.worktree_store
 7166            .read(cx)
 7167            .visible_worktrees(cx)
 7168            .filter_map(|worktree| {
 7169                let worktree = worktree.read(cx);
 7170                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7171            })
 7172            .flat_map(move |(worktree, summaries)| {
 7173                let worktree_id = worktree.id();
 7174                summaries
 7175                    .iter()
 7176                    .filter(move |(path, _)| {
 7177                        include_ignored
 7178                            || worktree
 7179                                .entry_for_path(path.as_ref())
 7180                                .is_some_and(|entry| !entry.is_ignored)
 7181                    })
 7182                    .flat_map(move |(path, summaries)| {
 7183                        summaries.iter().map(move |(server_id, summary)| {
 7184                            (
 7185                                ProjectPath {
 7186                                    worktree_id,
 7187                                    path: path.clone(),
 7188                                },
 7189                                *server_id,
 7190                                *summary,
 7191                            )
 7192                        })
 7193                    })
 7194            })
 7195    }
 7196
 7197    pub fn on_buffer_edited(
 7198        &mut self,
 7199        buffer: Entity<Buffer>,
 7200        cx: &mut Context<Self>,
 7201    ) -> Option<()> {
 7202        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7203            Some(
 7204                self.as_local()?
 7205                    .language_servers_for_buffer(buffer, cx)
 7206                    .map(|i| i.1.clone())
 7207                    .collect(),
 7208            )
 7209        })?;
 7210
 7211        let buffer = buffer.read(cx);
 7212        let file = File::from_dyn(buffer.file())?;
 7213        let abs_path = file.as_local()?.abs_path(cx);
 7214        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7215        let next_snapshot = buffer.text_snapshot();
 7216        for language_server in language_servers {
 7217            let language_server = language_server.clone();
 7218
 7219            let buffer_snapshots = self
 7220                .as_local_mut()
 7221                .unwrap()
 7222                .buffer_snapshots
 7223                .get_mut(&buffer.remote_id())
 7224                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7225            let previous_snapshot = buffer_snapshots.last()?;
 7226
 7227            let build_incremental_change = || {
 7228                buffer
 7229                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7230                        previous_snapshot.snapshot.version(),
 7231                    )
 7232                    .map(|edit| {
 7233                        let edit_start = edit.new.start.0;
 7234                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7235                        let new_text = next_snapshot
 7236                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7237                            .collect();
 7238                        lsp::TextDocumentContentChangeEvent {
 7239                            range: Some(lsp::Range::new(
 7240                                point_to_lsp(edit_start),
 7241                                point_to_lsp(edit_end),
 7242                            )),
 7243                            range_length: None,
 7244                            text: new_text,
 7245                        }
 7246                    })
 7247                    .collect()
 7248            };
 7249
 7250            let document_sync_kind = language_server
 7251                .capabilities()
 7252                .text_document_sync
 7253                .as_ref()
 7254                .and_then(|sync| match sync {
 7255                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7256                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7257                });
 7258
 7259            let content_changes: Vec<_> = match document_sync_kind {
 7260                Some(lsp::TextDocumentSyncKind::FULL) => {
 7261                    vec![lsp::TextDocumentContentChangeEvent {
 7262                        range: None,
 7263                        range_length: None,
 7264                        text: next_snapshot.text(),
 7265                    }]
 7266                }
 7267                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7268                _ => {
 7269                    #[cfg(any(test, feature = "test-support"))]
 7270                    {
 7271                        build_incremental_change()
 7272                    }
 7273
 7274                    #[cfg(not(any(test, feature = "test-support")))]
 7275                    {
 7276                        continue;
 7277                    }
 7278                }
 7279            };
 7280
 7281            let next_version = previous_snapshot.version + 1;
 7282            buffer_snapshots.push(LspBufferSnapshot {
 7283                version: next_version,
 7284                snapshot: next_snapshot.clone(),
 7285            });
 7286
 7287            language_server
 7288                .notify::<lsp::notification::DidChangeTextDocument>(
 7289                    &lsp::DidChangeTextDocumentParams {
 7290                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7291                            uri.clone(),
 7292                            next_version,
 7293                        ),
 7294                        content_changes,
 7295                    },
 7296                )
 7297                .ok();
 7298            self.pull_workspace_diagnostics(language_server.server_id());
 7299        }
 7300
 7301        None
 7302    }
 7303
 7304    pub fn on_buffer_saved(
 7305        &mut self,
 7306        buffer: Entity<Buffer>,
 7307        cx: &mut Context<Self>,
 7308    ) -> Option<()> {
 7309        let file = File::from_dyn(buffer.read(cx).file())?;
 7310        let worktree_id = file.worktree_id(cx);
 7311        let abs_path = file.as_local()?.abs_path(cx);
 7312        let text_document = lsp::TextDocumentIdentifier {
 7313            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7314        };
 7315        let local = self.as_local()?;
 7316
 7317        for server in local.language_servers_for_worktree(worktree_id) {
 7318            if let Some(include_text) = include_text(server.as_ref()) {
 7319                let text = if include_text {
 7320                    Some(buffer.read(cx).text())
 7321                } else {
 7322                    None
 7323                };
 7324                server
 7325                    .notify::<lsp::notification::DidSaveTextDocument>(
 7326                        &lsp::DidSaveTextDocumentParams {
 7327                            text_document: text_document.clone(),
 7328                            text,
 7329                        },
 7330                    )
 7331                    .ok();
 7332            }
 7333        }
 7334
 7335        let language_servers = buffer.update(cx, |buffer, cx| {
 7336            local.language_server_ids_for_buffer(buffer, cx)
 7337        });
 7338        for language_server_id in language_servers {
 7339            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7340        }
 7341
 7342        None
 7343    }
 7344
 7345    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7346        maybe!(async move {
 7347            let mut refreshed_servers = HashSet::default();
 7348            let servers = lsp_store
 7349                .update(cx, |lsp_store, cx| {
 7350                    let local = lsp_store.as_local()?;
 7351
 7352                    let servers = local
 7353                        .language_server_ids
 7354                        .iter()
 7355                        .filter_map(|(seed, state)| {
 7356                            let worktree = lsp_store
 7357                                .worktree_store
 7358                                .read(cx)
 7359                                .worktree_for_id(seed.worktree_id, cx);
 7360                            let delegate: Arc<dyn LspAdapterDelegate> =
 7361                                worktree.map(|worktree| {
 7362                                    LocalLspAdapterDelegate::new(
 7363                                        local.languages.clone(),
 7364                                        &local.environment,
 7365                                        cx.weak_entity(),
 7366                                        &worktree,
 7367                                        local.http_client.clone(),
 7368                                        local.fs.clone(),
 7369                                        cx,
 7370                                    )
 7371                                })?;
 7372                            let server_id = state.id;
 7373
 7374                            let states = local.language_servers.get(&server_id)?;
 7375
 7376                            match states {
 7377                                LanguageServerState::Starting { .. } => None,
 7378                                LanguageServerState::Running {
 7379                                    adapter, server, ..
 7380                                } => {
 7381                                    let adapter = adapter.clone();
 7382                                    let server = server.clone();
 7383                                    refreshed_servers.insert(server.name());
 7384                                    let toolchain = seed.toolchain.clone();
 7385                                    Some(cx.spawn(async move |_, cx| {
 7386                                        let settings =
 7387                                            LocalLspStore::workspace_configuration_for_adapter(
 7388                                                adapter.adapter.clone(),
 7389                                                &delegate,
 7390                                                toolchain,
 7391                                                cx,
 7392                                            )
 7393                                            .await
 7394                                            .ok()?;
 7395                                        server
 7396                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7397                                                &lsp::DidChangeConfigurationParams { settings },
 7398                                            )
 7399                                            .ok()?;
 7400                                        Some(())
 7401                                    }))
 7402                                }
 7403                            }
 7404                        })
 7405                        .collect::<Vec<_>>();
 7406
 7407                    Some(servers)
 7408                })
 7409                .ok()
 7410                .flatten()?;
 7411
 7412            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7413            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7414            // to stop and unregister its language server wrapper.
 7415            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7416            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7417            let _: Vec<Option<()>> = join_all(servers).await;
 7418
 7419            Some(())
 7420        })
 7421        .await;
 7422    }
 7423
 7424    fn maintain_workspace_config(
 7425        external_refresh_requests: watch::Receiver<()>,
 7426        cx: &mut Context<Self>,
 7427    ) -> Task<Result<()>> {
 7428        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7429        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7430
 7431        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7432            *settings_changed_tx.borrow_mut() = ();
 7433        });
 7434
 7435        let mut joint_future =
 7436            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7437        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7438        // - 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).
 7439        // - 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.
 7440        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7441        // - 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,
 7442        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7443        cx.spawn(async move |this, cx| {
 7444            while let Some(()) = joint_future.next().await {
 7445                this.update(cx, |this, cx| {
 7446                    this.refresh_server_tree(cx);
 7447                })
 7448                .ok();
 7449
 7450                Self::refresh_workspace_configurations(&this, cx).await;
 7451            }
 7452
 7453            drop(settings_observation);
 7454            anyhow::Ok(())
 7455        })
 7456    }
 7457
 7458    pub fn language_servers_for_local_buffer<'a>(
 7459        &'a self,
 7460        buffer: &Buffer,
 7461        cx: &mut App,
 7462    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7463        let local = self.as_local();
 7464        let language_server_ids = local
 7465            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7466            .unwrap_or_default();
 7467
 7468        language_server_ids
 7469            .into_iter()
 7470            .filter_map(
 7471                move |server_id| match local?.language_servers.get(&server_id)? {
 7472                    LanguageServerState::Running {
 7473                        adapter, server, ..
 7474                    } => Some((adapter, server)),
 7475                    _ => None,
 7476                },
 7477            )
 7478    }
 7479
 7480    pub fn language_server_for_local_buffer<'a>(
 7481        &'a self,
 7482        buffer: &'a Buffer,
 7483        server_id: LanguageServerId,
 7484        cx: &'a mut App,
 7485    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7486        self.as_local()?
 7487            .language_servers_for_buffer(buffer, cx)
 7488            .find(|(_, s)| s.server_id() == server_id)
 7489    }
 7490
 7491    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7492        self.diagnostic_summaries.remove(&id_to_remove);
 7493        if let Some(local) = self.as_local_mut() {
 7494            let to_remove = local.remove_worktree(id_to_remove, cx);
 7495            for server in to_remove {
 7496                self.language_server_statuses.remove(&server);
 7497            }
 7498        }
 7499    }
 7500
 7501    pub fn shared(
 7502        &mut self,
 7503        project_id: u64,
 7504        downstream_client: AnyProtoClient,
 7505        _: &mut Context<Self>,
 7506    ) {
 7507        self.downstream_client = Some((downstream_client.clone(), project_id));
 7508
 7509        for (server_id, status) in &self.language_server_statuses {
 7510            if let Some(server) = self.language_server_for_id(*server_id) {
 7511                downstream_client
 7512                    .send(proto::StartLanguageServer {
 7513                        project_id,
 7514                        server: Some(proto::LanguageServer {
 7515                            id: server_id.to_proto(),
 7516                            name: status.name.to_string(),
 7517                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7518                        }),
 7519                        capabilities: serde_json::to_string(&server.capabilities())
 7520                            .expect("serializing server LSP capabilities"),
 7521                    })
 7522                    .log_err();
 7523            }
 7524        }
 7525    }
 7526
 7527    pub fn disconnected_from_host(&mut self) {
 7528        self.downstream_client.take();
 7529    }
 7530
 7531    pub fn disconnected_from_ssh_remote(&mut self) {
 7532        if let LspStoreMode::Remote(RemoteLspStore {
 7533            upstream_client, ..
 7534        }) = &mut self.mode
 7535        {
 7536            upstream_client.take();
 7537        }
 7538    }
 7539
 7540    pub(crate) fn set_language_server_statuses_from_proto(
 7541        &mut self,
 7542        project: WeakEntity<Project>,
 7543        language_servers: Vec<proto::LanguageServer>,
 7544        server_capabilities: Vec<String>,
 7545        cx: &mut Context<Self>,
 7546    ) {
 7547        let lsp_logs = cx
 7548            .try_global::<GlobalLogStore>()
 7549            .map(|lsp_store| lsp_store.0.clone());
 7550
 7551        self.language_server_statuses = language_servers
 7552            .into_iter()
 7553            .zip(server_capabilities)
 7554            .map(|(server, server_capabilities)| {
 7555                let server_id = LanguageServerId(server.id as usize);
 7556                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7557                    self.lsp_server_capabilities
 7558                        .insert(server_id, server_capabilities);
 7559                }
 7560
 7561                let name = LanguageServerName::from_proto(server.name);
 7562                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7563
 7564                if let Some(lsp_logs) = &lsp_logs {
 7565                    lsp_logs.update(cx, |lsp_logs, cx| {
 7566                        lsp_logs.add_language_server(
 7567                            // Only remote clients get their language servers set from proto
 7568                            LanguageServerKind::Remote {
 7569                                project: project.clone(),
 7570                            },
 7571                            server_id,
 7572                            Some(name.clone()),
 7573                            worktree,
 7574                            None,
 7575                            cx,
 7576                        );
 7577                    });
 7578                }
 7579
 7580                (
 7581                    server_id,
 7582                    LanguageServerStatus {
 7583                        name,
 7584                        pending_work: Default::default(),
 7585                        has_pending_diagnostic_updates: false,
 7586                        progress_tokens: Default::default(),
 7587                        worktree,
 7588                    },
 7589                )
 7590            })
 7591            .collect();
 7592    }
 7593
 7594    #[cfg(test)]
 7595    pub fn update_diagnostic_entries(
 7596        &mut self,
 7597        server_id: LanguageServerId,
 7598        abs_path: PathBuf,
 7599        result_id: Option<String>,
 7600        version: Option<i32>,
 7601        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7602        cx: &mut Context<Self>,
 7603    ) -> anyhow::Result<()> {
 7604        self.merge_diagnostic_entries(
 7605            vec![DocumentDiagnosticsUpdate {
 7606                diagnostics: DocumentDiagnostics {
 7607                    diagnostics,
 7608                    document_abs_path: abs_path,
 7609                    version,
 7610                },
 7611                result_id,
 7612                server_id,
 7613                disk_based_sources: Cow::Borrowed(&[]),
 7614            }],
 7615            |_, _, _| false,
 7616            cx,
 7617        )?;
 7618        Ok(())
 7619    }
 7620
 7621    pub fn merge_diagnostic_entries<'a>(
 7622        &mut self,
 7623        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7624        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7625        cx: &mut Context<Self>,
 7626    ) -> anyhow::Result<()> {
 7627        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7628        let mut updated_diagnostics_paths = HashMap::default();
 7629        for mut update in diagnostic_updates {
 7630            let abs_path = &update.diagnostics.document_abs_path;
 7631            let server_id = update.server_id;
 7632            let Some((worktree, relative_path)) =
 7633                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7634            else {
 7635                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7636                return Ok(());
 7637            };
 7638
 7639            let worktree_id = worktree.read(cx).id();
 7640            let project_path = ProjectPath {
 7641                worktree_id,
 7642                path: relative_path.into(),
 7643            };
 7644
 7645            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7646                let snapshot = buffer_handle.read(cx).snapshot();
 7647                let buffer = buffer_handle.read(cx);
 7648                let reused_diagnostics = buffer
 7649                    .buffer_diagnostics(Some(server_id))
 7650                    .iter()
 7651                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 7652                    .map(|v| {
 7653                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7654                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7655                        DiagnosticEntry {
 7656                            range: start..end,
 7657                            diagnostic: v.diagnostic.clone(),
 7658                        }
 7659                    })
 7660                    .collect::<Vec<_>>();
 7661
 7662                self.as_local_mut()
 7663                    .context("cannot merge diagnostics on a remote LspStore")?
 7664                    .update_buffer_diagnostics(
 7665                        &buffer_handle,
 7666                        server_id,
 7667                        update.result_id,
 7668                        update.diagnostics.version,
 7669                        update.diagnostics.diagnostics.clone(),
 7670                        reused_diagnostics.clone(),
 7671                        cx,
 7672                    )?;
 7673
 7674                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7675            }
 7676
 7677            let updated = worktree.update(cx, |worktree, cx| {
 7678                self.update_worktree_diagnostics(
 7679                    worktree.id(),
 7680                    server_id,
 7681                    project_path.path.clone(),
 7682                    update.diagnostics.diagnostics,
 7683                    cx,
 7684                )
 7685            })?;
 7686            match updated {
 7687                ControlFlow::Continue(new_summary) => {
 7688                    if let Some((project_id, new_summary)) = new_summary {
 7689                        match &mut diagnostics_summary {
 7690                            Some(diagnostics_summary) => {
 7691                                diagnostics_summary
 7692                                    .more_summaries
 7693                                    .push(proto::DiagnosticSummary {
 7694                                        path: project_path.path.as_ref().to_proto(),
 7695                                        language_server_id: server_id.0 as u64,
 7696                                        error_count: new_summary.error_count,
 7697                                        warning_count: new_summary.warning_count,
 7698                                    })
 7699                            }
 7700                            None => {
 7701                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7702                                    project_id,
 7703                                    worktree_id: worktree_id.to_proto(),
 7704                                    summary: Some(proto::DiagnosticSummary {
 7705                                        path: project_path.path.as_ref().to_proto(),
 7706                                        language_server_id: server_id.0 as u64,
 7707                                        error_count: new_summary.error_count,
 7708                                        warning_count: new_summary.warning_count,
 7709                                    }),
 7710                                    more_summaries: Vec::new(),
 7711                                })
 7712                            }
 7713                        }
 7714                    }
 7715                    updated_diagnostics_paths
 7716                        .entry(server_id)
 7717                        .or_insert_with(Vec::new)
 7718                        .push(project_path);
 7719                }
 7720                ControlFlow::Break(()) => {}
 7721            }
 7722        }
 7723
 7724        if let Some((diagnostics_summary, (downstream_client, _))) =
 7725            diagnostics_summary.zip(self.downstream_client.as_ref())
 7726        {
 7727            downstream_client.send(diagnostics_summary).log_err();
 7728        }
 7729        for (server_id, paths) in updated_diagnostics_paths {
 7730            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7731        }
 7732        Ok(())
 7733    }
 7734
 7735    fn update_worktree_diagnostics(
 7736        &mut self,
 7737        worktree_id: WorktreeId,
 7738        server_id: LanguageServerId,
 7739        path_in_worktree: Arc<Path>,
 7740        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7741        _: &mut Context<Worktree>,
 7742    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7743        let local = match &mut self.mode {
 7744            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7745            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7746        };
 7747
 7748        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7749        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7750        let summaries_by_server_id = summaries_for_tree
 7751            .entry(path_in_worktree.clone())
 7752            .or_default();
 7753
 7754        let old_summary = summaries_by_server_id
 7755            .remove(&server_id)
 7756            .unwrap_or_default();
 7757
 7758        let new_summary = DiagnosticSummary::new(&diagnostics);
 7759        if new_summary.is_empty() {
 7760            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7761            {
 7762                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7763                    diagnostics_by_server_id.remove(ix);
 7764                }
 7765                if diagnostics_by_server_id.is_empty() {
 7766                    diagnostics_for_tree.remove(&path_in_worktree);
 7767                }
 7768            }
 7769        } else {
 7770            summaries_by_server_id.insert(server_id, new_summary);
 7771            let diagnostics_by_server_id = diagnostics_for_tree
 7772                .entry(path_in_worktree.clone())
 7773                .or_default();
 7774            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7775                Ok(ix) => {
 7776                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7777                }
 7778                Err(ix) => {
 7779                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7780                }
 7781            }
 7782        }
 7783
 7784        if !old_summary.is_empty() || !new_summary.is_empty() {
 7785            if let Some((_, project_id)) = &self.downstream_client {
 7786                Ok(ControlFlow::Continue(Some((
 7787                    *project_id,
 7788                    proto::DiagnosticSummary {
 7789                        path: path_in_worktree.to_proto(),
 7790                        language_server_id: server_id.0 as u64,
 7791                        error_count: new_summary.error_count as u32,
 7792                        warning_count: new_summary.warning_count as u32,
 7793                    },
 7794                ))))
 7795            } else {
 7796                Ok(ControlFlow::Continue(None))
 7797            }
 7798        } else {
 7799            Ok(ControlFlow::Break(()))
 7800        }
 7801    }
 7802
 7803    pub fn open_buffer_for_symbol(
 7804        &mut self,
 7805        symbol: &Symbol,
 7806        cx: &mut Context<Self>,
 7807    ) -> Task<Result<Entity<Buffer>>> {
 7808        if let Some((client, project_id)) = self.upstream_client() {
 7809            let request = client.request(proto::OpenBufferForSymbol {
 7810                project_id,
 7811                symbol: Some(Self::serialize_symbol(symbol)),
 7812            });
 7813            cx.spawn(async move |this, cx| {
 7814                let response = request.await?;
 7815                let buffer_id = BufferId::new(response.buffer_id)?;
 7816                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7817                    .await
 7818            })
 7819        } else if let Some(local) = self.as_local() {
 7820            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7821                seed.worktree_id == symbol.source_worktree_id
 7822                    && state.id == symbol.source_language_server_id
 7823                    && symbol.language_server_name == seed.name
 7824            });
 7825            if !is_valid {
 7826                return Task::ready(Err(anyhow!(
 7827                    "language server for worktree and language not found"
 7828                )));
 7829            };
 7830
 7831            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7832                .worktree_store
 7833                .read(cx)
 7834                .worktree_for_id(symbol.path.worktree_id, cx)
 7835                .map(|worktree| worktree.read(cx).abs_path())
 7836            {
 7837                worktree_abs_path
 7838            } else {
 7839                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7840            };
 7841
 7842            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7843            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 7844                uri
 7845            } else {
 7846                return Task::ready(Err(anyhow!("invalid symbol path")));
 7847            };
 7848
 7849            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7850        } else {
 7851            Task::ready(Err(anyhow!("no upstream client or local store")))
 7852        }
 7853    }
 7854
 7855    pub(crate) fn open_local_buffer_via_lsp(
 7856        &mut self,
 7857        abs_path: lsp::Uri,
 7858        language_server_id: LanguageServerId,
 7859        cx: &mut Context<Self>,
 7860    ) -> Task<Result<Entity<Buffer>>> {
 7861        cx.spawn(async move |lsp_store, cx| {
 7862            // Escape percent-encoded string.
 7863            let current_scheme = abs_path.scheme().to_owned();
 7864            // Uri is immutable, so we can't modify the scheme
 7865
 7866            let abs_path = abs_path
 7867                .to_file_path()
 7868                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7869            let p = abs_path.clone();
 7870            let yarn_worktree = lsp_store
 7871                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7872                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7873                        cx.spawn(async move |this, cx| {
 7874                            let t = this
 7875                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7876                                .ok()?;
 7877                            t.await
 7878                        })
 7879                    }),
 7880                    None => Task::ready(None),
 7881                })?
 7882                .await;
 7883            let (worktree_root_target, known_relative_path) =
 7884                if let Some((zip_root, relative_path)) = yarn_worktree {
 7885                    (zip_root, Some(relative_path))
 7886                } else {
 7887                    (Arc::<Path>::from(abs_path.as_path()), None)
 7888                };
 7889            let (worktree, relative_path) = if let Some(result) =
 7890                lsp_store.update(cx, |lsp_store, cx| {
 7891                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7892                        worktree_store.find_worktree(&worktree_root_target, cx)
 7893                    })
 7894                })? {
 7895                let relative_path =
 7896                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7897                (result.0, relative_path)
 7898            } else {
 7899                let worktree = lsp_store
 7900                    .update(cx, |lsp_store, cx| {
 7901                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7902                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7903                        })
 7904                    })?
 7905                    .await?;
 7906                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7907                    lsp_store
 7908                        .update(cx, |lsp_store, cx| {
 7909                            if let Some(local) = lsp_store.as_local_mut() {
 7910                                local.register_language_server_for_invisible_worktree(
 7911                                    &worktree,
 7912                                    language_server_id,
 7913                                    cx,
 7914                                )
 7915                            }
 7916                        })
 7917                        .ok();
 7918                }
 7919                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7920                let relative_path = if let Some(known_path) = known_relative_path {
 7921                    known_path
 7922                } else {
 7923                    abs_path.strip_prefix(worktree_root)?.into()
 7924                };
 7925                (worktree, relative_path)
 7926            };
 7927            let project_path = ProjectPath {
 7928                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7929                path: relative_path,
 7930            };
 7931            lsp_store
 7932                .update(cx, |lsp_store, cx| {
 7933                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7934                        buffer_store.open_buffer(project_path, cx)
 7935                    })
 7936                })?
 7937                .await
 7938        })
 7939    }
 7940
 7941    fn request_multiple_lsp_locally<P, R>(
 7942        &mut self,
 7943        buffer: &Entity<Buffer>,
 7944        position: Option<P>,
 7945        request: R,
 7946        cx: &mut Context<Self>,
 7947    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7948    where
 7949        P: ToOffset,
 7950        R: LspCommand + Clone,
 7951        <R::LspRequest as lsp::request::Request>::Result: Send,
 7952        <R::LspRequest as lsp::request::Request>::Params: Send,
 7953    {
 7954        let Some(local) = self.as_local() else {
 7955            return Task::ready(Vec::new());
 7956        };
 7957
 7958        let snapshot = buffer.read(cx).snapshot();
 7959        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7960
 7961        let server_ids = buffer.update(cx, |buffer, cx| {
 7962            local
 7963                .language_servers_for_buffer(buffer, cx)
 7964                .filter(|(adapter, _)| {
 7965                    scope
 7966                        .as_ref()
 7967                        .map(|scope| scope.language_allowed(&adapter.name))
 7968                        .unwrap_or(true)
 7969                })
 7970                .map(|(_, server)| server.server_id())
 7971                .filter(|server_id| {
 7972                    self.as_local().is_none_or(|local| {
 7973                        local
 7974                            .buffers_opened_in_servers
 7975                            .get(&snapshot.remote_id())
 7976                            .is_some_and(|servers| servers.contains(server_id))
 7977                    })
 7978                })
 7979                .collect::<Vec<_>>()
 7980        });
 7981
 7982        let mut response_results = server_ids
 7983            .into_iter()
 7984            .map(|server_id| {
 7985                let task = self.request_lsp(
 7986                    buffer.clone(),
 7987                    LanguageServerToQuery::Other(server_id),
 7988                    request.clone(),
 7989                    cx,
 7990                );
 7991                async move { (server_id, task.await) }
 7992            })
 7993            .collect::<FuturesUnordered<_>>();
 7994
 7995        cx.background_spawn(async move {
 7996            let mut responses = Vec::with_capacity(response_results.len());
 7997            while let Some((server_id, response_result)) = response_results.next().await {
 7998                if let Some(response) = response_result.log_err() {
 7999                    responses.push((server_id, response));
 8000                }
 8001            }
 8002            responses
 8003        })
 8004    }
 8005
 8006    async fn handle_lsp_command<T: LspCommand>(
 8007        this: Entity<Self>,
 8008        envelope: TypedEnvelope<T::ProtoRequest>,
 8009        mut cx: AsyncApp,
 8010    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8011    where
 8012        <T::LspRequest as lsp::request::Request>::Params: Send,
 8013        <T::LspRequest as lsp::request::Request>::Result: Send,
 8014    {
 8015        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8016        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8017        let buffer_handle = this.update(&mut cx, |this, cx| {
 8018            this.buffer_store.read(cx).get_existing(buffer_id)
 8019        })??;
 8020        let request = T::from_proto(
 8021            envelope.payload,
 8022            this.clone(),
 8023            buffer_handle.clone(),
 8024            cx.clone(),
 8025        )
 8026        .await?;
 8027        let response = this
 8028            .update(&mut cx, |this, cx| {
 8029                this.request_lsp(
 8030                    buffer_handle.clone(),
 8031                    LanguageServerToQuery::FirstCapable,
 8032                    request,
 8033                    cx,
 8034                )
 8035            })?
 8036            .await?;
 8037        this.update(&mut cx, |this, cx| {
 8038            Ok(T::response_to_proto(
 8039                response,
 8040                this,
 8041                sender_id,
 8042                &buffer_handle.read(cx).version(),
 8043                cx,
 8044            ))
 8045        })?
 8046    }
 8047
 8048    async fn handle_lsp_query(
 8049        lsp_store: Entity<Self>,
 8050        envelope: TypedEnvelope<proto::LspQuery>,
 8051        mut cx: AsyncApp,
 8052    ) -> Result<proto::Ack> {
 8053        use proto::lsp_query::Request;
 8054        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8055        let lsp_query = envelope.payload;
 8056        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8057        match lsp_query.request.context("invalid LSP query request")? {
 8058            Request::GetReferences(get_references) => {
 8059                let position = get_references.position.clone().and_then(deserialize_anchor);
 8060                Self::query_lsp_locally::<GetReferences>(
 8061                    lsp_store,
 8062                    sender_id,
 8063                    lsp_request_id,
 8064                    get_references,
 8065                    position,
 8066                    cx.clone(),
 8067                )
 8068                .await?;
 8069            }
 8070            Request::GetDocumentColor(get_document_color) => {
 8071                Self::query_lsp_locally::<GetDocumentColor>(
 8072                    lsp_store,
 8073                    sender_id,
 8074                    lsp_request_id,
 8075                    get_document_color,
 8076                    None,
 8077                    cx.clone(),
 8078                )
 8079                .await?;
 8080            }
 8081            Request::GetHover(get_hover) => {
 8082                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8083                Self::query_lsp_locally::<GetHover>(
 8084                    lsp_store,
 8085                    sender_id,
 8086                    lsp_request_id,
 8087                    get_hover,
 8088                    position,
 8089                    cx.clone(),
 8090                )
 8091                .await?;
 8092            }
 8093            Request::GetCodeActions(get_code_actions) => {
 8094                Self::query_lsp_locally::<GetCodeActions>(
 8095                    lsp_store,
 8096                    sender_id,
 8097                    lsp_request_id,
 8098                    get_code_actions,
 8099                    None,
 8100                    cx.clone(),
 8101                )
 8102                .await?;
 8103            }
 8104            Request::GetSignatureHelp(get_signature_help) => {
 8105                let position = get_signature_help
 8106                    .position
 8107                    .clone()
 8108                    .and_then(deserialize_anchor);
 8109                Self::query_lsp_locally::<GetSignatureHelp>(
 8110                    lsp_store,
 8111                    sender_id,
 8112                    lsp_request_id,
 8113                    get_signature_help,
 8114                    position,
 8115                    cx.clone(),
 8116                )
 8117                .await?;
 8118            }
 8119            Request::GetCodeLens(get_code_lens) => {
 8120                Self::query_lsp_locally::<GetCodeLens>(
 8121                    lsp_store,
 8122                    sender_id,
 8123                    lsp_request_id,
 8124                    get_code_lens,
 8125                    None,
 8126                    cx.clone(),
 8127                )
 8128                .await?;
 8129            }
 8130            Request::GetDefinition(get_definition) => {
 8131                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8132                Self::query_lsp_locally::<GetDefinitions>(
 8133                    lsp_store,
 8134                    sender_id,
 8135                    lsp_request_id,
 8136                    get_definition,
 8137                    position,
 8138                    cx.clone(),
 8139                )
 8140                .await?;
 8141            }
 8142            Request::GetDeclaration(get_declaration) => {
 8143                let position = get_declaration
 8144                    .position
 8145                    .clone()
 8146                    .and_then(deserialize_anchor);
 8147                Self::query_lsp_locally::<GetDeclarations>(
 8148                    lsp_store,
 8149                    sender_id,
 8150                    lsp_request_id,
 8151                    get_declaration,
 8152                    position,
 8153                    cx.clone(),
 8154                )
 8155                .await?;
 8156            }
 8157            Request::GetTypeDefinition(get_type_definition) => {
 8158                let position = get_type_definition
 8159                    .position
 8160                    .clone()
 8161                    .and_then(deserialize_anchor);
 8162                Self::query_lsp_locally::<GetTypeDefinitions>(
 8163                    lsp_store,
 8164                    sender_id,
 8165                    lsp_request_id,
 8166                    get_type_definition,
 8167                    position,
 8168                    cx.clone(),
 8169                )
 8170                .await?;
 8171            }
 8172            Request::GetImplementation(get_implementation) => {
 8173                let position = get_implementation
 8174                    .position
 8175                    .clone()
 8176                    .and_then(deserialize_anchor);
 8177                Self::query_lsp_locally::<GetImplementations>(
 8178                    lsp_store,
 8179                    sender_id,
 8180                    lsp_request_id,
 8181                    get_implementation,
 8182                    position,
 8183                    cx.clone(),
 8184                )
 8185                .await?;
 8186            }
 8187            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8188            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8189                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8190                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8191                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8192                    this.buffer_store.read(cx).get_existing(buffer_id)
 8193                })??;
 8194                buffer
 8195                    .update(&mut cx, |buffer, _| {
 8196                        buffer.wait_for_version(version.clone())
 8197                    })?
 8198                    .await?;
 8199                lsp_store.update(&mut cx, |lsp_store, cx| {
 8200                    let existing_queries = lsp_store
 8201                        .running_lsp_requests
 8202                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8203                        .or_default();
 8204                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8205                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8206                    {
 8207                        existing_queries.1.clear();
 8208                    }
 8209                    existing_queries.1.insert(
 8210                        lsp_request_id,
 8211                        cx.spawn(async move |lsp_store, cx| {
 8212                            let diagnostics_pull = lsp_store
 8213                                .update(cx, |lsp_store, cx| {
 8214                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8215                                })
 8216                                .ok();
 8217                            if let Some(diagnostics_pull) = diagnostics_pull {
 8218                                match diagnostics_pull.await {
 8219                                    Ok(()) => {}
 8220                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8221                                };
 8222                            }
 8223                        }),
 8224                    );
 8225                })?;
 8226            }
 8227        }
 8228        Ok(proto::Ack {})
 8229    }
 8230
 8231    async fn handle_lsp_query_response(
 8232        lsp_store: Entity<Self>,
 8233        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8234        cx: AsyncApp,
 8235    ) -> Result<()> {
 8236        lsp_store.read_with(&cx, |lsp_store, _| {
 8237            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8238                upstream_client.handle_lsp_response(envelope.clone());
 8239            }
 8240        })?;
 8241        Ok(())
 8242    }
 8243
 8244    async fn handle_apply_code_action(
 8245        this: Entity<Self>,
 8246        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8247        mut cx: AsyncApp,
 8248    ) -> Result<proto::ApplyCodeActionResponse> {
 8249        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8250        let action =
 8251            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8252        let apply_code_action = this.update(&mut cx, |this, cx| {
 8253            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8254            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8255            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8256        })??;
 8257
 8258        let project_transaction = apply_code_action.await?;
 8259        let project_transaction = this.update(&mut cx, |this, cx| {
 8260            this.buffer_store.update(cx, |buffer_store, cx| {
 8261                buffer_store.serialize_project_transaction_for_peer(
 8262                    project_transaction,
 8263                    sender_id,
 8264                    cx,
 8265                )
 8266            })
 8267        })?;
 8268        Ok(proto::ApplyCodeActionResponse {
 8269            transaction: Some(project_transaction),
 8270        })
 8271    }
 8272
 8273    async fn handle_register_buffer_with_language_servers(
 8274        this: Entity<Self>,
 8275        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8276        mut cx: AsyncApp,
 8277    ) -> Result<proto::Ack> {
 8278        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8279        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8280        this.update(&mut cx, |this, cx| {
 8281            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8282                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8283                    project_id: upstream_project_id,
 8284                    buffer_id: buffer_id.to_proto(),
 8285                    only_servers: envelope.payload.only_servers,
 8286                });
 8287            }
 8288
 8289            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8290                anyhow::bail!("buffer is not open");
 8291            };
 8292
 8293            let handle = this.register_buffer_with_language_servers(
 8294                &buffer,
 8295                envelope
 8296                    .payload
 8297                    .only_servers
 8298                    .into_iter()
 8299                    .filter_map(|selector| {
 8300                        Some(match selector.selector? {
 8301                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8302                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8303                            }
 8304                            proto::language_server_selector::Selector::Name(name) => {
 8305                                LanguageServerSelector::Name(LanguageServerName(
 8306                                    SharedString::from(name),
 8307                                ))
 8308                            }
 8309                        })
 8310                    })
 8311                    .collect(),
 8312                false,
 8313                cx,
 8314            );
 8315            this.buffer_store().update(cx, |buffer_store, _| {
 8316                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8317            });
 8318
 8319            Ok(())
 8320        })??;
 8321        Ok(proto::Ack {})
 8322    }
 8323
 8324    async fn handle_rename_project_entry(
 8325        this: Entity<Self>,
 8326        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8327        mut cx: AsyncApp,
 8328    ) -> Result<proto::ProjectEntryResponse> {
 8329        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8330        let (worktree_id, worktree, old_path, is_dir) = this
 8331            .update(&mut cx, |this, cx| {
 8332                this.worktree_store
 8333                    .read(cx)
 8334                    .worktree_and_entry_for_id(entry_id, cx)
 8335                    .map(|(worktree, entry)| {
 8336                        (
 8337                            worktree.read(cx).id(),
 8338                            worktree,
 8339                            entry.path.clone(),
 8340                            entry.is_dir(),
 8341                        )
 8342                    })
 8343            })?
 8344            .context("worktree not found")?;
 8345        let (old_abs_path, new_abs_path) = {
 8346            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8347            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8348            (root_path.join(&old_path), root_path.join(&new_path))
 8349        };
 8350
 8351        let _transaction = Self::will_rename_entry(
 8352            this.downgrade(),
 8353            worktree_id,
 8354            &old_abs_path,
 8355            &new_abs_path,
 8356            is_dir,
 8357            cx.clone(),
 8358        )
 8359        .await;
 8360        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8361        this.read_with(&cx, |this, _| {
 8362            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8363        })
 8364        .ok();
 8365        response
 8366    }
 8367
 8368    async fn handle_update_diagnostic_summary(
 8369        this: Entity<Self>,
 8370        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8371        mut cx: AsyncApp,
 8372    ) -> Result<()> {
 8373        this.update(&mut cx, |lsp_store, cx| {
 8374            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8375            let mut updated_diagnostics_paths = HashMap::default();
 8376            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8377            for message_summary in envelope
 8378                .payload
 8379                .summary
 8380                .into_iter()
 8381                .chain(envelope.payload.more_summaries)
 8382            {
 8383                let project_path = ProjectPath {
 8384                    worktree_id,
 8385                    path: Arc::<Path>::from_proto(message_summary.path),
 8386                };
 8387                let path = project_path.path.clone();
 8388                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8389                let summary = DiagnosticSummary {
 8390                    error_count: message_summary.error_count as usize,
 8391                    warning_count: message_summary.warning_count as usize,
 8392                };
 8393
 8394                if summary.is_empty() {
 8395                    if let Some(worktree_summaries) =
 8396                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8397                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8398                    {
 8399                        summaries.remove(&server_id);
 8400                        if summaries.is_empty() {
 8401                            worktree_summaries.remove(&path);
 8402                        }
 8403                    }
 8404                } else {
 8405                    lsp_store
 8406                        .diagnostic_summaries
 8407                        .entry(worktree_id)
 8408                        .or_default()
 8409                        .entry(path)
 8410                        .or_default()
 8411                        .insert(server_id, summary);
 8412                }
 8413
 8414                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8415                    match &mut diagnostics_summary {
 8416                        Some(diagnostics_summary) => {
 8417                            diagnostics_summary
 8418                                .more_summaries
 8419                                .push(proto::DiagnosticSummary {
 8420                                    path: project_path.path.as_ref().to_proto(),
 8421                                    language_server_id: server_id.0 as u64,
 8422                                    error_count: summary.error_count as u32,
 8423                                    warning_count: summary.warning_count as u32,
 8424                                })
 8425                        }
 8426                        None => {
 8427                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8428                                project_id: *project_id,
 8429                                worktree_id: worktree_id.to_proto(),
 8430                                summary: Some(proto::DiagnosticSummary {
 8431                                    path: project_path.path.as_ref().to_proto(),
 8432                                    language_server_id: server_id.0 as u64,
 8433                                    error_count: summary.error_count as u32,
 8434                                    warning_count: summary.warning_count as u32,
 8435                                }),
 8436                                more_summaries: Vec::new(),
 8437                            })
 8438                        }
 8439                    }
 8440                }
 8441                updated_diagnostics_paths
 8442                    .entry(server_id)
 8443                    .or_insert_with(Vec::new)
 8444                    .push(project_path);
 8445            }
 8446
 8447            if let Some((diagnostics_summary, (downstream_client, _))) =
 8448                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8449            {
 8450                downstream_client.send(diagnostics_summary).log_err();
 8451            }
 8452            for (server_id, paths) in updated_diagnostics_paths {
 8453                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8454            }
 8455            Ok(())
 8456        })?
 8457    }
 8458
 8459    async fn handle_start_language_server(
 8460        lsp_store: Entity<Self>,
 8461        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8462        mut cx: AsyncApp,
 8463    ) -> Result<()> {
 8464        let server = envelope.payload.server.context("invalid server")?;
 8465        let server_capabilities =
 8466            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8467                .with_context(|| {
 8468                    format!(
 8469                        "incorrect server capabilities {}",
 8470                        envelope.payload.capabilities
 8471                    )
 8472                })?;
 8473        lsp_store.update(&mut cx, |lsp_store, cx| {
 8474            let server_id = LanguageServerId(server.id as usize);
 8475            let server_name = LanguageServerName::from_proto(server.name.clone());
 8476            lsp_store
 8477                .lsp_server_capabilities
 8478                .insert(server_id, server_capabilities);
 8479            lsp_store.language_server_statuses.insert(
 8480                server_id,
 8481                LanguageServerStatus {
 8482                    name: server_name.clone(),
 8483                    pending_work: Default::default(),
 8484                    has_pending_diagnostic_updates: false,
 8485                    progress_tokens: Default::default(),
 8486                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8487                },
 8488            );
 8489            cx.emit(LspStoreEvent::LanguageServerAdded(
 8490                server_id,
 8491                server_name,
 8492                server.worktree_id.map(WorktreeId::from_proto),
 8493            ));
 8494            cx.notify();
 8495        })?;
 8496        Ok(())
 8497    }
 8498
 8499    async fn handle_update_language_server(
 8500        lsp_store: Entity<Self>,
 8501        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8502        mut cx: AsyncApp,
 8503    ) -> Result<()> {
 8504        lsp_store.update(&mut cx, |lsp_store, cx| {
 8505            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8506
 8507            match envelope.payload.variant.context("invalid variant")? {
 8508                proto::update_language_server::Variant::WorkStart(payload) => {
 8509                    lsp_store.on_lsp_work_start(
 8510                        language_server_id,
 8511                        payload.token,
 8512                        LanguageServerProgress {
 8513                            title: payload.title,
 8514                            is_disk_based_diagnostics_progress: false,
 8515                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8516                            message: payload.message,
 8517                            percentage: payload.percentage.map(|p| p as usize),
 8518                            last_update_at: cx.background_executor().now(),
 8519                        },
 8520                        cx,
 8521                    );
 8522                }
 8523                proto::update_language_server::Variant::WorkProgress(payload) => {
 8524                    lsp_store.on_lsp_work_progress(
 8525                        language_server_id,
 8526                        payload.token,
 8527                        LanguageServerProgress {
 8528                            title: None,
 8529                            is_disk_based_diagnostics_progress: false,
 8530                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8531                            message: payload.message,
 8532                            percentage: payload.percentage.map(|p| p as usize),
 8533                            last_update_at: cx.background_executor().now(),
 8534                        },
 8535                        cx,
 8536                    );
 8537                }
 8538
 8539                proto::update_language_server::Variant::WorkEnd(payload) => {
 8540                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8541                }
 8542
 8543                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8544                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8545                }
 8546
 8547                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8548                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8549                }
 8550
 8551                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8552                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8553                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8554                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8555                        language_server_id,
 8556                        name: envelope
 8557                            .payload
 8558                            .server_name
 8559                            .map(SharedString::new)
 8560                            .map(LanguageServerName),
 8561                        message: non_lsp,
 8562                    });
 8563                }
 8564            }
 8565
 8566            Ok(())
 8567        })?
 8568    }
 8569
 8570    async fn handle_language_server_log(
 8571        this: Entity<Self>,
 8572        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8573        mut cx: AsyncApp,
 8574    ) -> Result<()> {
 8575        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8576        let log_type = envelope
 8577            .payload
 8578            .log_type
 8579            .map(LanguageServerLogType::from_proto)
 8580            .context("invalid language server log type")?;
 8581
 8582        let message = envelope.payload.message;
 8583
 8584        this.update(&mut cx, |_, cx| {
 8585            cx.emit(LspStoreEvent::LanguageServerLog(
 8586                language_server_id,
 8587                log_type,
 8588                message,
 8589            ));
 8590        })
 8591    }
 8592
 8593    async fn handle_lsp_ext_cancel_flycheck(
 8594        lsp_store: Entity<Self>,
 8595        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 8596        cx: AsyncApp,
 8597    ) -> Result<proto::Ack> {
 8598        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8599        lsp_store.read_with(&cx, |lsp_store, _| {
 8600            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8601                server
 8602                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 8603                    .context("handling lsp ext cancel flycheck")
 8604            } else {
 8605                anyhow::Ok(())
 8606            }
 8607        })??;
 8608
 8609        Ok(proto::Ack {})
 8610    }
 8611
 8612    async fn handle_lsp_ext_run_flycheck(
 8613        lsp_store: Entity<Self>,
 8614        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 8615        mut cx: AsyncApp,
 8616    ) -> Result<proto::Ack> {
 8617        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8618        lsp_store.update(&mut cx, |lsp_store, cx| {
 8619            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8620                let text_document = if envelope.payload.current_file_only {
 8621                    let buffer_id = envelope
 8622                        .payload
 8623                        .buffer_id
 8624                        .map(|id| BufferId::new(id))
 8625                        .transpose()?;
 8626                    buffer_id
 8627                        .and_then(|buffer_id| {
 8628                            lsp_store
 8629                                .buffer_store()
 8630                                .read(cx)
 8631                                .get(buffer_id)
 8632                                .and_then(|buffer| {
 8633                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 8634                                })
 8635                                .map(|path| make_text_document_identifier(&path))
 8636                        })
 8637                        .transpose()?
 8638                } else {
 8639                    None
 8640                };
 8641                server
 8642                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 8643                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 8644                    )
 8645                    .context("handling lsp ext run flycheck")
 8646            } else {
 8647                anyhow::Ok(())
 8648            }
 8649        })??;
 8650
 8651        Ok(proto::Ack {})
 8652    }
 8653
 8654    async fn handle_lsp_ext_clear_flycheck(
 8655        lsp_store: Entity<Self>,
 8656        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 8657        cx: AsyncApp,
 8658    ) -> Result<proto::Ack> {
 8659        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8660        lsp_store.read_with(&cx, |lsp_store, _| {
 8661            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 8662                server
 8663                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 8664                    .context("handling lsp ext clear flycheck")
 8665            } else {
 8666                anyhow::Ok(())
 8667            }
 8668        })??;
 8669
 8670        Ok(proto::Ack {})
 8671    }
 8672
 8673    pub fn disk_based_diagnostics_started(
 8674        &mut self,
 8675        language_server_id: LanguageServerId,
 8676        cx: &mut Context<Self>,
 8677    ) {
 8678        if let Some(language_server_status) =
 8679            self.language_server_statuses.get_mut(&language_server_id)
 8680        {
 8681            language_server_status.has_pending_diagnostic_updates = true;
 8682        }
 8683
 8684        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 8685        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8686            language_server_id,
 8687            name: self
 8688                .language_server_adapter_for_id(language_server_id)
 8689                .map(|adapter| adapter.name()),
 8690            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 8691                Default::default(),
 8692            ),
 8693        })
 8694    }
 8695
 8696    pub fn disk_based_diagnostics_finished(
 8697        &mut self,
 8698        language_server_id: LanguageServerId,
 8699        cx: &mut Context<Self>,
 8700    ) {
 8701        if let Some(language_server_status) =
 8702            self.language_server_statuses.get_mut(&language_server_id)
 8703        {
 8704            language_server_status.has_pending_diagnostic_updates = false;
 8705        }
 8706
 8707        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 8708        cx.emit(LspStoreEvent::LanguageServerUpdate {
 8709            language_server_id,
 8710            name: self
 8711                .language_server_adapter_for_id(language_server_id)
 8712                .map(|adapter| adapter.name()),
 8713            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 8714                Default::default(),
 8715            ),
 8716        })
 8717    }
 8718
 8719    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 8720    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 8721    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 8722    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 8723    // the language server might take some time to publish diagnostics.
 8724    fn simulate_disk_based_diagnostics_events_if_needed(
 8725        &mut self,
 8726        language_server_id: LanguageServerId,
 8727        cx: &mut Context<Self>,
 8728    ) {
 8729        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 8730
 8731        let Some(LanguageServerState::Running {
 8732            simulate_disk_based_diagnostics_completion,
 8733            adapter,
 8734            ..
 8735        }) = self
 8736            .as_local_mut()
 8737            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 8738        else {
 8739            return;
 8740        };
 8741
 8742        if adapter.disk_based_diagnostics_progress_token.is_some() {
 8743            return;
 8744        }
 8745
 8746        let prev_task =
 8747            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 8748                cx.background_executor()
 8749                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 8750                    .await;
 8751
 8752                this.update(cx, |this, cx| {
 8753                    this.disk_based_diagnostics_finished(language_server_id, cx);
 8754
 8755                    if let Some(LanguageServerState::Running {
 8756                        simulate_disk_based_diagnostics_completion,
 8757                        ..
 8758                    }) = this.as_local_mut().and_then(|local_store| {
 8759                        local_store.language_servers.get_mut(&language_server_id)
 8760                    }) {
 8761                        *simulate_disk_based_diagnostics_completion = None;
 8762                    }
 8763                })
 8764                .ok();
 8765            }));
 8766
 8767        if prev_task.is_none() {
 8768            self.disk_based_diagnostics_started(language_server_id, cx);
 8769        }
 8770    }
 8771
 8772    pub fn language_server_statuses(
 8773        &self,
 8774    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 8775        self.language_server_statuses
 8776            .iter()
 8777            .map(|(key, value)| (*key, value))
 8778    }
 8779
 8780    pub(super) fn did_rename_entry(
 8781        &self,
 8782        worktree_id: WorktreeId,
 8783        old_path: &Path,
 8784        new_path: &Path,
 8785        is_dir: bool,
 8786    ) {
 8787        maybe!({
 8788            let local_store = self.as_local()?;
 8789
 8790            let old_uri = lsp::Uri::from_file_path(old_path)
 8791                .ok()
 8792                .map(|uri| uri.to_string())?;
 8793            let new_uri = lsp::Uri::from_file_path(new_path)
 8794                .ok()
 8795                .map(|uri| uri.to_string())?;
 8796
 8797            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8798                let Some(filter) = local_store
 8799                    .language_server_paths_watched_for_rename
 8800                    .get(&language_server.server_id())
 8801                else {
 8802                    continue;
 8803                };
 8804
 8805                if filter.should_send_did_rename(&old_uri, is_dir) {
 8806                    language_server
 8807                        .notify::<DidRenameFiles>(&RenameFilesParams {
 8808                            files: vec![FileRename {
 8809                                old_uri: old_uri.clone(),
 8810                                new_uri: new_uri.clone(),
 8811                            }],
 8812                        })
 8813                        .ok();
 8814                }
 8815            }
 8816            Some(())
 8817        });
 8818    }
 8819
 8820    pub(super) fn will_rename_entry(
 8821        this: WeakEntity<Self>,
 8822        worktree_id: WorktreeId,
 8823        old_path: &Path,
 8824        new_path: &Path,
 8825        is_dir: bool,
 8826        cx: AsyncApp,
 8827    ) -> Task<ProjectTransaction> {
 8828        let old_uri = lsp::Uri::from_file_path(old_path)
 8829            .ok()
 8830            .map(|uri| uri.to_string());
 8831        let new_uri = lsp::Uri::from_file_path(new_path)
 8832            .ok()
 8833            .map(|uri| uri.to_string());
 8834        cx.spawn(async move |cx| {
 8835            let mut tasks = vec![];
 8836            this.update(cx, |this, cx| {
 8837                let local_store = this.as_local()?;
 8838                let old_uri = old_uri?;
 8839                let new_uri = new_uri?;
 8840                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 8841                    let Some(filter) = local_store
 8842                        .language_server_paths_watched_for_rename
 8843                        .get(&language_server.server_id())
 8844                    else {
 8845                        continue;
 8846                    };
 8847
 8848                    if filter.should_send_will_rename(&old_uri, is_dir) {
 8849                        let apply_edit = cx.spawn({
 8850                            let old_uri = old_uri.clone();
 8851                            let new_uri = new_uri.clone();
 8852                            let language_server = language_server.clone();
 8853                            async move |this, cx| {
 8854                                let edit = language_server
 8855                                    .request::<WillRenameFiles>(RenameFilesParams {
 8856                                        files: vec![FileRename { old_uri, new_uri }],
 8857                                    })
 8858                                    .await
 8859                                    .into_response()
 8860                                    .context("will rename files")
 8861                                    .log_err()
 8862                                    .flatten()?;
 8863
 8864                                let transaction = LocalLspStore::deserialize_workspace_edit(
 8865                                    this.upgrade()?,
 8866                                    edit,
 8867                                    false,
 8868                                    language_server.clone(),
 8869                                    cx,
 8870                                )
 8871                                .await
 8872                                .ok()?;
 8873                                Some(transaction)
 8874                            }
 8875                        });
 8876                        tasks.push(apply_edit);
 8877                    }
 8878                }
 8879                Some(())
 8880            })
 8881            .ok()
 8882            .flatten();
 8883            let mut merged_transaction = ProjectTransaction::default();
 8884            for task in tasks {
 8885                // Await on tasks sequentially so that the order of application of edits is deterministic
 8886                // (at least with regards to the order of registration of language servers)
 8887                if let Some(transaction) = task.await {
 8888                    for (buffer, buffer_transaction) in transaction.0 {
 8889                        merged_transaction.0.insert(buffer, buffer_transaction);
 8890                    }
 8891                }
 8892            }
 8893            merged_transaction
 8894        })
 8895    }
 8896
 8897    fn lsp_notify_abs_paths_changed(
 8898        &mut self,
 8899        server_id: LanguageServerId,
 8900        changes: Vec<PathEvent>,
 8901    ) {
 8902        maybe!({
 8903            let server = self.language_server_for_id(server_id)?;
 8904            let changes = changes
 8905                .into_iter()
 8906                .filter_map(|event| {
 8907                    let typ = match event.kind? {
 8908                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 8909                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 8910                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 8911                    };
 8912                    Some(lsp::FileEvent {
 8913                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 8914                        typ,
 8915                    })
 8916                })
 8917                .collect::<Vec<_>>();
 8918            if !changes.is_empty() {
 8919                server
 8920                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 8921                        &lsp::DidChangeWatchedFilesParams { changes },
 8922                    )
 8923                    .ok();
 8924            }
 8925            Some(())
 8926        });
 8927    }
 8928
 8929    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 8930        self.as_local()?.language_server_for_id(id)
 8931    }
 8932
 8933    fn on_lsp_progress(
 8934        &mut self,
 8935        progress: lsp::ProgressParams,
 8936        language_server_id: LanguageServerId,
 8937        disk_based_diagnostics_progress_token: Option<String>,
 8938        cx: &mut Context<Self>,
 8939    ) {
 8940        let token = match progress.token {
 8941            lsp::NumberOrString::String(token) => token,
 8942            lsp::NumberOrString::Number(token) => {
 8943                log::info!("skipping numeric progress token {}", token);
 8944                return;
 8945            }
 8946        };
 8947
 8948        match progress.value {
 8949            lsp::ProgressParamsValue::WorkDone(progress) => {
 8950                self.handle_work_done_progress(
 8951                    progress,
 8952                    language_server_id,
 8953                    disk_based_diagnostics_progress_token,
 8954                    token,
 8955                    cx,
 8956                );
 8957            }
 8958            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 8959                if let Some(LanguageServerState::Running {
 8960                    workspace_refresh_task: Some(workspace_refresh_task),
 8961                    ..
 8962                }) = self
 8963                    .as_local_mut()
 8964                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 8965                {
 8966                    workspace_refresh_task.progress_tx.try_send(()).ok();
 8967                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 8968                }
 8969            }
 8970        }
 8971    }
 8972
 8973    fn handle_work_done_progress(
 8974        &mut self,
 8975        progress: lsp::WorkDoneProgress,
 8976        language_server_id: LanguageServerId,
 8977        disk_based_diagnostics_progress_token: Option<String>,
 8978        token: String,
 8979        cx: &mut Context<Self>,
 8980    ) {
 8981        let language_server_status =
 8982            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 8983                status
 8984            } else {
 8985                return;
 8986            };
 8987
 8988        if !language_server_status.progress_tokens.contains(&token) {
 8989            return;
 8990        }
 8991
 8992        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 8993            .as_ref()
 8994            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 8995
 8996        match progress {
 8997            lsp::WorkDoneProgress::Begin(report) => {
 8998                if is_disk_based_diagnostics_progress {
 8999                    self.disk_based_diagnostics_started(language_server_id, cx);
 9000                }
 9001                self.on_lsp_work_start(
 9002                    language_server_id,
 9003                    token.clone(),
 9004                    LanguageServerProgress {
 9005                        title: Some(report.title),
 9006                        is_disk_based_diagnostics_progress,
 9007                        is_cancellable: report.cancellable.unwrap_or(false),
 9008                        message: report.message.clone(),
 9009                        percentage: report.percentage.map(|p| p as usize),
 9010                        last_update_at: cx.background_executor().now(),
 9011                    },
 9012                    cx,
 9013                );
 9014            }
 9015            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9016                language_server_id,
 9017                token,
 9018                LanguageServerProgress {
 9019                    title: None,
 9020                    is_disk_based_diagnostics_progress,
 9021                    is_cancellable: report.cancellable.unwrap_or(false),
 9022                    message: report.message,
 9023                    percentage: report.percentage.map(|p| p as usize),
 9024                    last_update_at: cx.background_executor().now(),
 9025                },
 9026                cx,
 9027            ),
 9028            lsp::WorkDoneProgress::End(_) => {
 9029                language_server_status.progress_tokens.remove(&token);
 9030                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9031                if is_disk_based_diagnostics_progress {
 9032                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9033                }
 9034            }
 9035        }
 9036    }
 9037
 9038    fn on_lsp_work_start(
 9039        &mut self,
 9040        language_server_id: LanguageServerId,
 9041        token: String,
 9042        progress: LanguageServerProgress,
 9043        cx: &mut Context<Self>,
 9044    ) {
 9045        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9046            status.pending_work.insert(token.clone(), progress.clone());
 9047            cx.notify();
 9048        }
 9049        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9050            language_server_id,
 9051            name: self
 9052                .language_server_adapter_for_id(language_server_id)
 9053                .map(|adapter| adapter.name()),
 9054            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9055                token,
 9056                title: progress.title,
 9057                message: progress.message,
 9058                percentage: progress.percentage.map(|p| p as u32),
 9059                is_cancellable: Some(progress.is_cancellable),
 9060            }),
 9061        })
 9062    }
 9063
 9064    fn on_lsp_work_progress(
 9065        &mut self,
 9066        language_server_id: LanguageServerId,
 9067        token: String,
 9068        progress: LanguageServerProgress,
 9069        cx: &mut Context<Self>,
 9070    ) {
 9071        let mut did_update = false;
 9072        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9073            match status.pending_work.entry(token.clone()) {
 9074                btree_map::Entry::Vacant(entry) => {
 9075                    entry.insert(progress.clone());
 9076                    did_update = true;
 9077                }
 9078                btree_map::Entry::Occupied(mut entry) => {
 9079                    let entry = entry.get_mut();
 9080                    if (progress.last_update_at - entry.last_update_at)
 9081                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9082                    {
 9083                        entry.last_update_at = progress.last_update_at;
 9084                        if progress.message.is_some() {
 9085                            entry.message = progress.message.clone();
 9086                        }
 9087                        if progress.percentage.is_some() {
 9088                            entry.percentage = progress.percentage;
 9089                        }
 9090                        if progress.is_cancellable != entry.is_cancellable {
 9091                            entry.is_cancellable = progress.is_cancellable;
 9092                        }
 9093                        did_update = true;
 9094                    }
 9095                }
 9096            }
 9097        }
 9098
 9099        if did_update {
 9100            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9101                language_server_id,
 9102                name: self
 9103                    .language_server_adapter_for_id(language_server_id)
 9104                    .map(|adapter| adapter.name()),
 9105                message: proto::update_language_server::Variant::WorkProgress(
 9106                    proto::LspWorkProgress {
 9107                        token,
 9108                        message: progress.message,
 9109                        percentage: progress.percentage.map(|p| p as u32),
 9110                        is_cancellable: Some(progress.is_cancellable),
 9111                    },
 9112                ),
 9113            })
 9114        }
 9115    }
 9116
 9117    fn on_lsp_work_end(
 9118        &mut self,
 9119        language_server_id: LanguageServerId,
 9120        token: String,
 9121        cx: &mut Context<Self>,
 9122    ) {
 9123        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9124            if let Some(work) = status.pending_work.remove(&token)
 9125                && !work.is_disk_based_diagnostics_progress
 9126            {
 9127                cx.emit(LspStoreEvent::RefreshInlayHints);
 9128            }
 9129            cx.notify();
 9130        }
 9131
 9132        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9133            language_server_id,
 9134            name: self
 9135                .language_server_adapter_for_id(language_server_id)
 9136                .map(|adapter| adapter.name()),
 9137            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9138        })
 9139    }
 9140
 9141    pub async fn handle_resolve_completion_documentation(
 9142        this: Entity<Self>,
 9143        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9144        mut cx: AsyncApp,
 9145    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9146        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9147
 9148        let completion = this
 9149            .read_with(&cx, |this, cx| {
 9150                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9151                let server = this
 9152                    .language_server_for_id(id)
 9153                    .with_context(|| format!("No language server {id}"))?;
 9154
 9155                anyhow::Ok(cx.background_spawn(async move {
 9156                    let can_resolve = server
 9157                        .capabilities()
 9158                        .completion_provider
 9159                        .as_ref()
 9160                        .and_then(|options| options.resolve_provider)
 9161                        .unwrap_or(false);
 9162                    if can_resolve {
 9163                        server
 9164                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9165                            .await
 9166                            .into_response()
 9167                            .context("resolve completion item")
 9168                    } else {
 9169                        anyhow::Ok(lsp_completion)
 9170                    }
 9171                }))
 9172            })??
 9173            .await?;
 9174
 9175        let mut documentation_is_markdown = false;
 9176        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9177        let documentation = match completion.documentation {
 9178            Some(lsp::Documentation::String(text)) => text,
 9179
 9180            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9181                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9182                value
 9183            }
 9184
 9185            _ => String::new(),
 9186        };
 9187
 9188        // If we have a new buffer_id, that means we're talking to a new client
 9189        // and want to check for new text_edits in the completion too.
 9190        let mut old_replace_start = None;
 9191        let mut old_replace_end = None;
 9192        let mut old_insert_start = None;
 9193        let mut old_insert_end = None;
 9194        let mut new_text = String::default();
 9195        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9196            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9197                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9198                anyhow::Ok(buffer.read(cx).snapshot())
 9199            })??;
 9200
 9201            if let Some(text_edit) = completion.text_edit.as_ref() {
 9202                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9203
 9204                if let Some(mut edit) = edit {
 9205                    LineEnding::normalize(&mut edit.new_text);
 9206
 9207                    new_text = edit.new_text;
 9208                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9209                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9210                    if let Some(insert_range) = edit.insert_range {
 9211                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9212                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9213                    }
 9214                }
 9215            }
 9216        }
 9217
 9218        Ok(proto::ResolveCompletionDocumentationResponse {
 9219            documentation,
 9220            documentation_is_markdown,
 9221            old_replace_start,
 9222            old_replace_end,
 9223            new_text,
 9224            lsp_completion,
 9225            old_insert_start,
 9226            old_insert_end,
 9227        })
 9228    }
 9229
 9230    async fn handle_on_type_formatting(
 9231        this: Entity<Self>,
 9232        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9233        mut cx: AsyncApp,
 9234    ) -> Result<proto::OnTypeFormattingResponse> {
 9235        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9236            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9237            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9238            let position = envelope
 9239                .payload
 9240                .position
 9241                .and_then(deserialize_anchor)
 9242                .context("invalid position")?;
 9243            anyhow::Ok(this.apply_on_type_formatting(
 9244                buffer,
 9245                position,
 9246                envelope.payload.trigger.clone(),
 9247                cx,
 9248            ))
 9249        })??;
 9250
 9251        let transaction = on_type_formatting
 9252            .await?
 9253            .as_ref()
 9254            .map(language::proto::serialize_transaction);
 9255        Ok(proto::OnTypeFormattingResponse { transaction })
 9256    }
 9257
 9258    async fn handle_refresh_inlay_hints(
 9259        this: Entity<Self>,
 9260        _: TypedEnvelope<proto::RefreshInlayHints>,
 9261        mut cx: AsyncApp,
 9262    ) -> Result<proto::Ack> {
 9263        this.update(&mut cx, |_, cx| {
 9264            cx.emit(LspStoreEvent::RefreshInlayHints);
 9265        })?;
 9266        Ok(proto::Ack {})
 9267    }
 9268
 9269    async fn handle_pull_workspace_diagnostics(
 9270        lsp_store: Entity<Self>,
 9271        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9272        mut cx: AsyncApp,
 9273    ) -> Result<proto::Ack> {
 9274        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9275        lsp_store.update(&mut cx, |lsp_store, _| {
 9276            lsp_store.pull_workspace_diagnostics(server_id);
 9277        })?;
 9278        Ok(proto::Ack {})
 9279    }
 9280
 9281    async fn handle_inlay_hints(
 9282        this: Entity<Self>,
 9283        envelope: TypedEnvelope<proto::InlayHints>,
 9284        mut cx: AsyncApp,
 9285    ) -> Result<proto::InlayHintsResponse> {
 9286        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9287        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9288        let buffer = this.update(&mut cx, |this, cx| {
 9289            this.buffer_store.read(cx).get_existing(buffer_id)
 9290        })??;
 9291        buffer
 9292            .update(&mut cx, |buffer, _| {
 9293                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9294            })?
 9295            .await
 9296            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9297
 9298        let start = envelope
 9299            .payload
 9300            .start
 9301            .and_then(deserialize_anchor)
 9302            .context("missing range start")?;
 9303        let end = envelope
 9304            .payload
 9305            .end
 9306            .and_then(deserialize_anchor)
 9307            .context("missing range end")?;
 9308        let buffer_hints = this
 9309            .update(&mut cx, |lsp_store, cx| {
 9310                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9311            })?
 9312            .await
 9313            .context("inlay hints fetch")?;
 9314
 9315        this.update(&mut cx, |project, cx| {
 9316            InlayHints::response_to_proto(
 9317                buffer_hints,
 9318                project,
 9319                sender_id,
 9320                &buffer.read(cx).version(),
 9321                cx,
 9322            )
 9323        })
 9324    }
 9325
 9326    async fn handle_get_color_presentation(
 9327        lsp_store: Entity<Self>,
 9328        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9329        mut cx: AsyncApp,
 9330    ) -> Result<proto::GetColorPresentationResponse> {
 9331        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9332        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9333            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9334        })??;
 9335
 9336        let color = envelope
 9337            .payload
 9338            .color
 9339            .context("invalid color resolve request")?;
 9340        let start = color
 9341            .lsp_range_start
 9342            .context("invalid color resolve request")?;
 9343        let end = color
 9344            .lsp_range_end
 9345            .context("invalid color resolve request")?;
 9346
 9347        let color = DocumentColor {
 9348            lsp_range: lsp::Range {
 9349                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9350                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9351            },
 9352            color: lsp::Color {
 9353                red: color.red,
 9354                green: color.green,
 9355                blue: color.blue,
 9356                alpha: color.alpha,
 9357            },
 9358            resolved: false,
 9359            color_presentations: Vec::new(),
 9360        };
 9361        let resolved_color = lsp_store
 9362            .update(&mut cx, |lsp_store, cx| {
 9363                lsp_store.resolve_color_presentation(
 9364                    color,
 9365                    buffer.clone(),
 9366                    LanguageServerId(envelope.payload.server_id as usize),
 9367                    cx,
 9368                )
 9369            })?
 9370            .await
 9371            .context("resolving color presentation")?;
 9372
 9373        Ok(proto::GetColorPresentationResponse {
 9374            presentations: resolved_color
 9375                .color_presentations
 9376                .into_iter()
 9377                .map(|presentation| proto::ColorPresentation {
 9378                    label: presentation.label.to_string(),
 9379                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9380                    additional_text_edits: presentation
 9381                        .additional_text_edits
 9382                        .into_iter()
 9383                        .map(serialize_lsp_edit)
 9384                        .collect(),
 9385                })
 9386                .collect(),
 9387        })
 9388    }
 9389
 9390    async fn handle_resolve_inlay_hint(
 9391        this: Entity<Self>,
 9392        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9393        mut cx: AsyncApp,
 9394    ) -> Result<proto::ResolveInlayHintResponse> {
 9395        let proto_hint = envelope
 9396            .payload
 9397            .hint
 9398            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9399        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9400            .context("resolved proto inlay hint conversion")?;
 9401        let buffer = this.update(&mut cx, |this, cx| {
 9402            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9403            this.buffer_store.read(cx).get_existing(buffer_id)
 9404        })??;
 9405        let response_hint = this
 9406            .update(&mut cx, |this, cx| {
 9407                this.resolve_inlay_hint(
 9408                    hint,
 9409                    buffer,
 9410                    LanguageServerId(envelope.payload.language_server_id as usize),
 9411                    cx,
 9412                )
 9413            })?
 9414            .await
 9415            .context("inlay hints fetch")?;
 9416        Ok(proto::ResolveInlayHintResponse {
 9417            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9418        })
 9419    }
 9420
 9421    async fn handle_refresh_code_lens(
 9422        this: Entity<Self>,
 9423        _: TypedEnvelope<proto::RefreshCodeLens>,
 9424        mut cx: AsyncApp,
 9425    ) -> Result<proto::Ack> {
 9426        this.update(&mut cx, |_, cx| {
 9427            cx.emit(LspStoreEvent::RefreshCodeLens);
 9428        })?;
 9429        Ok(proto::Ack {})
 9430    }
 9431
 9432    async fn handle_open_buffer_for_symbol(
 9433        this: Entity<Self>,
 9434        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9435        mut cx: AsyncApp,
 9436    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9437        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9438        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9439        let symbol = Self::deserialize_symbol(symbol)?;
 9440        let symbol = this.read_with(&cx, |this, _| {
 9441            let signature = this.symbol_signature(&symbol.path);
 9442            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9443            Ok(symbol)
 9444        })??;
 9445        let buffer = this
 9446            .update(&mut cx, |this, cx| {
 9447                this.open_buffer_for_symbol(
 9448                    &Symbol {
 9449                        language_server_name: symbol.language_server_name,
 9450                        source_worktree_id: symbol.source_worktree_id,
 9451                        source_language_server_id: symbol.source_language_server_id,
 9452                        path: symbol.path,
 9453                        name: symbol.name,
 9454                        kind: symbol.kind,
 9455                        range: symbol.range,
 9456                        signature: symbol.signature,
 9457                        label: CodeLabel {
 9458                            text: Default::default(),
 9459                            runs: Default::default(),
 9460                            filter_range: Default::default(),
 9461                        },
 9462                    },
 9463                    cx,
 9464                )
 9465            })?
 9466            .await?;
 9467
 9468        this.update(&mut cx, |this, cx| {
 9469            let is_private = buffer
 9470                .read(cx)
 9471                .file()
 9472                .map(|f| f.is_private())
 9473                .unwrap_or_default();
 9474            if is_private {
 9475                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9476            } else {
 9477                this.buffer_store
 9478                    .update(cx, |buffer_store, cx| {
 9479                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9480                    })
 9481                    .detach_and_log_err(cx);
 9482                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9483                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9484            }
 9485        })?
 9486    }
 9487
 9488    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9489        let mut hasher = Sha256::new();
 9490        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9491        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9492        hasher.update(self.nonce.to_be_bytes());
 9493        hasher.finalize().as_slice().try_into().unwrap()
 9494    }
 9495
 9496    pub async fn handle_get_project_symbols(
 9497        this: Entity<Self>,
 9498        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9499        mut cx: AsyncApp,
 9500    ) -> Result<proto::GetProjectSymbolsResponse> {
 9501        let symbols = this
 9502            .update(&mut cx, |this, cx| {
 9503                this.symbols(&envelope.payload.query, cx)
 9504            })?
 9505            .await?;
 9506
 9507        Ok(proto::GetProjectSymbolsResponse {
 9508            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9509        })
 9510    }
 9511
 9512    pub async fn handle_restart_language_servers(
 9513        this: Entity<Self>,
 9514        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9515        mut cx: AsyncApp,
 9516    ) -> Result<proto::Ack> {
 9517        this.update(&mut cx, |lsp_store, cx| {
 9518            let buffers =
 9519                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9520            lsp_store.restart_language_servers_for_buffers(
 9521                buffers,
 9522                envelope
 9523                    .payload
 9524                    .only_servers
 9525                    .into_iter()
 9526                    .filter_map(|selector| {
 9527                        Some(match selector.selector? {
 9528                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9529                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9530                            }
 9531                            proto::language_server_selector::Selector::Name(name) => {
 9532                                LanguageServerSelector::Name(LanguageServerName(
 9533                                    SharedString::from(name),
 9534                                ))
 9535                            }
 9536                        })
 9537                    })
 9538                    .collect(),
 9539                cx,
 9540            );
 9541        })?;
 9542
 9543        Ok(proto::Ack {})
 9544    }
 9545
 9546    pub async fn handle_stop_language_servers(
 9547        lsp_store: Entity<Self>,
 9548        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9549        mut cx: AsyncApp,
 9550    ) -> Result<proto::Ack> {
 9551        lsp_store.update(&mut cx, |lsp_store, cx| {
 9552            if envelope.payload.all
 9553                && envelope.payload.also_servers.is_empty()
 9554                && envelope.payload.buffer_ids.is_empty()
 9555            {
 9556                lsp_store.stop_all_language_servers(cx);
 9557            } else {
 9558                let buffers =
 9559                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9560                lsp_store
 9561                    .stop_language_servers_for_buffers(
 9562                        buffers,
 9563                        envelope
 9564                            .payload
 9565                            .also_servers
 9566                            .into_iter()
 9567                            .filter_map(|selector| {
 9568                                Some(match selector.selector? {
 9569                                    proto::language_server_selector::Selector::ServerId(
 9570                                        server_id,
 9571                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9572                                        server_id,
 9573                                    )),
 9574                                    proto::language_server_selector::Selector::Name(name) => {
 9575                                        LanguageServerSelector::Name(LanguageServerName(
 9576                                            SharedString::from(name),
 9577                                        ))
 9578                                    }
 9579                                })
 9580                            })
 9581                            .collect(),
 9582                        cx,
 9583                    )
 9584                    .detach_and_log_err(cx);
 9585            }
 9586        })?;
 9587
 9588        Ok(proto::Ack {})
 9589    }
 9590
 9591    pub async fn handle_cancel_language_server_work(
 9592        this: Entity<Self>,
 9593        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9594        mut cx: AsyncApp,
 9595    ) -> Result<proto::Ack> {
 9596        this.update(&mut cx, |this, cx| {
 9597            if let Some(work) = envelope.payload.work {
 9598                match work {
 9599                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9600                        let buffers =
 9601                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
 9602                        this.cancel_language_server_work_for_buffers(buffers, cx);
 9603                    }
 9604                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
 9605                        let server_id = LanguageServerId::from_proto(work.language_server_id);
 9606                        this.cancel_language_server_work(server_id, work.token, cx);
 9607                    }
 9608                }
 9609            }
 9610        })?;
 9611
 9612        Ok(proto::Ack {})
 9613    }
 9614
 9615    fn buffer_ids_to_buffers(
 9616        &mut self,
 9617        buffer_ids: impl Iterator<Item = u64>,
 9618        cx: &mut Context<Self>,
 9619    ) -> Vec<Entity<Buffer>> {
 9620        buffer_ids
 9621            .into_iter()
 9622            .flat_map(|buffer_id| {
 9623                self.buffer_store
 9624                    .read(cx)
 9625                    .get(BufferId::new(buffer_id).log_err()?)
 9626            })
 9627            .collect::<Vec<_>>()
 9628    }
 9629
 9630    async fn handle_apply_additional_edits_for_completion(
 9631        this: Entity<Self>,
 9632        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
 9633        mut cx: AsyncApp,
 9634    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
 9635        let (buffer, completion) = this.update(&mut cx, |this, cx| {
 9636            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9637            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9638            let completion = Self::deserialize_completion(
 9639                envelope.payload.completion.context("invalid completion")?,
 9640            )?;
 9641            anyhow::Ok((buffer, completion))
 9642        })??;
 9643
 9644        let apply_additional_edits = this.update(&mut cx, |this, cx| {
 9645            this.apply_additional_edits_for_completion(
 9646                buffer,
 9647                Rc::new(RefCell::new(Box::new([Completion {
 9648                    replace_range: completion.replace_range,
 9649                    new_text: completion.new_text,
 9650                    source: completion.source,
 9651                    documentation: None,
 9652                    label: CodeLabel {
 9653                        text: Default::default(),
 9654                        runs: Default::default(),
 9655                        filter_range: Default::default(),
 9656                    },
 9657                    insert_text_mode: None,
 9658                    icon_path: None,
 9659                    confirm: None,
 9660                }]))),
 9661                0,
 9662                false,
 9663                cx,
 9664            )
 9665        })?;
 9666
 9667        Ok(proto::ApplyCompletionAdditionalEditsResponse {
 9668            transaction: apply_additional_edits
 9669                .await?
 9670                .as_ref()
 9671                .map(language::proto::serialize_transaction),
 9672        })
 9673    }
 9674
 9675    pub fn last_formatting_failure(&self) -> Option<&str> {
 9676        self.last_formatting_failure.as_deref()
 9677    }
 9678
 9679    pub fn reset_last_formatting_failure(&mut self) {
 9680        self.last_formatting_failure = None;
 9681    }
 9682
 9683    pub fn environment_for_buffer(
 9684        &self,
 9685        buffer: &Entity<Buffer>,
 9686        cx: &mut Context<Self>,
 9687    ) -> Shared<Task<Option<HashMap<String, String>>>> {
 9688        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
 9689            environment.update(cx, |env, cx| {
 9690                env.get_buffer_environment(buffer, &self.worktree_store, cx)
 9691            })
 9692        } else {
 9693            Task::ready(None).shared()
 9694        }
 9695    }
 9696
 9697    pub fn format(
 9698        &mut self,
 9699        buffers: HashSet<Entity<Buffer>>,
 9700        target: LspFormatTarget,
 9701        push_to_history: bool,
 9702        trigger: FormatTrigger,
 9703        cx: &mut Context<Self>,
 9704    ) -> Task<anyhow::Result<ProjectTransaction>> {
 9705        let logger = zlog::scoped!("format");
 9706        if self.as_local().is_some() {
 9707            zlog::trace!(logger => "Formatting locally");
 9708            let logger = zlog::scoped!(logger => "local");
 9709            let buffers = buffers
 9710                .into_iter()
 9711                .map(|buffer_handle| {
 9712                    let buffer = buffer_handle.read(cx);
 9713                    let buffer_abs_path = File::from_dyn(buffer.file())
 9714                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
 9715
 9716                    (buffer_handle, buffer_abs_path, buffer.remote_id())
 9717                })
 9718                .collect::<Vec<_>>();
 9719
 9720            cx.spawn(async move |lsp_store, cx| {
 9721                let mut formattable_buffers = Vec::with_capacity(buffers.len());
 9722
 9723                for (handle, abs_path, id) in buffers {
 9724                    let env = lsp_store
 9725                        .update(cx, |lsp_store, cx| {
 9726                            lsp_store.environment_for_buffer(&handle, cx)
 9727                        })?
 9728                        .await;
 9729
 9730                    let ranges = match &target {
 9731                        LspFormatTarget::Buffers => None,
 9732                        LspFormatTarget::Ranges(ranges) => {
 9733                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
 9734                        }
 9735                    };
 9736
 9737                    formattable_buffers.push(FormattableBuffer {
 9738                        handle,
 9739                        abs_path,
 9740                        env,
 9741                        ranges,
 9742                    });
 9743                }
 9744                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
 9745
 9746                let format_timer = zlog::time!(logger => "Formatting buffers");
 9747                let result = LocalLspStore::format_locally(
 9748                    lsp_store.clone(),
 9749                    formattable_buffers,
 9750                    push_to_history,
 9751                    trigger,
 9752                    logger,
 9753                    cx,
 9754                )
 9755                .await;
 9756                format_timer.end();
 9757
 9758                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
 9759
 9760                lsp_store.update(cx, |lsp_store, _| {
 9761                    lsp_store.update_last_formatting_failure(&result);
 9762                })?;
 9763
 9764                result
 9765            })
 9766        } else if let Some((client, project_id)) = self.upstream_client() {
 9767            zlog::trace!(logger => "Formatting remotely");
 9768            let logger = zlog::scoped!(logger => "remote");
 9769            // Don't support formatting ranges via remote
 9770            match target {
 9771                LspFormatTarget::Buffers => {}
 9772                LspFormatTarget::Ranges(_) => {
 9773                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
 9774                    return Task::ready(Ok(ProjectTransaction::default()));
 9775                }
 9776            }
 9777
 9778            let buffer_store = self.buffer_store();
 9779            cx.spawn(async move |lsp_store, cx| {
 9780                zlog::trace!(logger => "Sending remote format request");
 9781                let request_timer = zlog::time!(logger => "remote format request");
 9782                let result = client
 9783                    .request(proto::FormatBuffers {
 9784                        project_id,
 9785                        trigger: trigger as i32,
 9786                        buffer_ids: buffers
 9787                            .iter()
 9788                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
 9789                            .collect::<Result<_>>()?,
 9790                    })
 9791                    .await
 9792                    .and_then(|result| result.transaction.context("missing transaction"));
 9793                request_timer.end();
 9794
 9795                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
 9796
 9797                lsp_store.update(cx, |lsp_store, _| {
 9798                    lsp_store.update_last_formatting_failure(&result);
 9799                })?;
 9800
 9801                let transaction_response = result?;
 9802                let _timer = zlog::time!(logger => "deserializing project transaction");
 9803                buffer_store
 9804                    .update(cx, |buffer_store, cx| {
 9805                        buffer_store.deserialize_project_transaction(
 9806                            transaction_response,
 9807                            push_to_history,
 9808                            cx,
 9809                        )
 9810                    })?
 9811                    .await
 9812            })
 9813        } else {
 9814            zlog::trace!(logger => "Not formatting");
 9815            Task::ready(Ok(ProjectTransaction::default()))
 9816        }
 9817    }
 9818
 9819    async fn handle_format_buffers(
 9820        this: Entity<Self>,
 9821        envelope: TypedEnvelope<proto::FormatBuffers>,
 9822        mut cx: AsyncApp,
 9823    ) -> Result<proto::FormatBuffersResponse> {
 9824        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9825        let format = this.update(&mut cx, |this, cx| {
 9826            let mut buffers = HashSet::default();
 9827            for buffer_id in &envelope.payload.buffer_ids {
 9828                let buffer_id = BufferId::new(*buffer_id)?;
 9829                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9830            }
 9831            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
 9832            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
 9833        })??;
 9834
 9835        let project_transaction = format.await?;
 9836        let project_transaction = this.update(&mut cx, |this, cx| {
 9837            this.buffer_store.update(cx, |buffer_store, cx| {
 9838                buffer_store.serialize_project_transaction_for_peer(
 9839                    project_transaction,
 9840                    sender_id,
 9841                    cx,
 9842                )
 9843            })
 9844        })?;
 9845        Ok(proto::FormatBuffersResponse {
 9846            transaction: Some(project_transaction),
 9847        })
 9848    }
 9849
 9850    async fn handle_apply_code_action_kind(
 9851        this: Entity<Self>,
 9852        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
 9853        mut cx: AsyncApp,
 9854    ) -> Result<proto::ApplyCodeActionKindResponse> {
 9855        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9856        let format = this.update(&mut cx, |this, cx| {
 9857            let mut buffers = HashSet::default();
 9858            for buffer_id in &envelope.payload.buffer_ids {
 9859                let buffer_id = BufferId::new(*buffer_id)?;
 9860                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
 9861            }
 9862            let kind = match envelope.payload.kind.as_str() {
 9863                "" => CodeActionKind::EMPTY,
 9864                "quickfix" => CodeActionKind::QUICKFIX,
 9865                "refactor" => CodeActionKind::REFACTOR,
 9866                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
 9867                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
 9868                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
 9869                "source" => CodeActionKind::SOURCE,
 9870                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
 9871                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
 9872                _ => anyhow::bail!(
 9873                    "Invalid code action kind {}",
 9874                    envelope.payload.kind.as_str()
 9875                ),
 9876            };
 9877            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
 9878        })??;
 9879
 9880        let project_transaction = format.await?;
 9881        let project_transaction = this.update(&mut cx, |this, cx| {
 9882            this.buffer_store.update(cx, |buffer_store, cx| {
 9883                buffer_store.serialize_project_transaction_for_peer(
 9884                    project_transaction,
 9885                    sender_id,
 9886                    cx,
 9887                )
 9888            })
 9889        })?;
 9890        Ok(proto::ApplyCodeActionKindResponse {
 9891            transaction: Some(project_transaction),
 9892        })
 9893    }
 9894
 9895    async fn shutdown_language_server(
 9896        server_state: Option<LanguageServerState>,
 9897        name: LanguageServerName,
 9898        cx: &mut AsyncApp,
 9899    ) {
 9900        let server = match server_state {
 9901            Some(LanguageServerState::Starting { startup, .. }) => {
 9902                let mut timer = cx
 9903                    .background_executor()
 9904                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
 9905                    .fuse();
 9906
 9907                select! {
 9908                    server = startup.fuse() => server,
 9909                    () = timer => {
 9910                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
 9911                        None
 9912                    },
 9913                }
 9914            }
 9915
 9916            Some(LanguageServerState::Running { server, .. }) => Some(server),
 9917
 9918            None => None,
 9919        };
 9920
 9921        if let Some(server) = server
 9922            && let Some(shutdown) = server.shutdown()
 9923        {
 9924            shutdown.await;
 9925        }
 9926    }
 9927
 9928    // Returns a list of all of the worktrees which no longer have a language server and the root path
 9929    // for the stopped server
 9930    fn stop_local_language_server(
 9931        &mut self,
 9932        server_id: LanguageServerId,
 9933        cx: &mut Context<Self>,
 9934    ) -> Task<()> {
 9935        let local = match &mut self.mode {
 9936            LspStoreMode::Local(local) => local,
 9937            _ => {
 9938                return Task::ready(());
 9939            }
 9940        };
 9941
 9942        // Remove this server ID from all entries in the given worktree.
 9943        local
 9944            .language_server_ids
 9945            .retain(|_, state| state.id != server_id);
 9946        self.buffer_store.update(cx, |buffer_store, cx| {
 9947            for buffer in buffer_store.buffers() {
 9948                buffer.update(cx, |buffer, cx| {
 9949                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 9950                    buffer.set_completion_triggers(server_id, Default::default(), cx);
 9951                });
 9952            }
 9953        });
 9954
 9955        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
 9956            summaries.retain(|path, summaries_by_server_id| {
 9957                if summaries_by_server_id.remove(&server_id).is_some() {
 9958                    if let Some((client, project_id)) = self.downstream_client.clone() {
 9959                        client
 9960                            .send(proto::UpdateDiagnosticSummary {
 9961                                project_id,
 9962                                worktree_id: worktree_id.to_proto(),
 9963                                summary: Some(proto::DiagnosticSummary {
 9964                                    path: path.as_ref().to_proto(),
 9965                                    language_server_id: server_id.0 as u64,
 9966                                    error_count: 0,
 9967                                    warning_count: 0,
 9968                                }),
 9969                                more_summaries: Vec::new(),
 9970                            })
 9971                            .log_err();
 9972                    }
 9973                    !summaries_by_server_id.is_empty()
 9974                } else {
 9975                    true
 9976                }
 9977            });
 9978        }
 9979
 9980        let local = self.as_local_mut().unwrap();
 9981        for diagnostics in local.diagnostics.values_mut() {
 9982            diagnostics.retain(|_, diagnostics_by_server_id| {
 9983                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 9984                    diagnostics_by_server_id.remove(ix);
 9985                    !diagnostics_by_server_id.is_empty()
 9986                } else {
 9987                    true
 9988                }
 9989            });
 9990        }
 9991        local.language_server_watched_paths.remove(&server_id);
 9992
 9993        let server_state = local.language_servers.remove(&server_id);
 9994        self.cleanup_lsp_data(server_id);
 9995        let name = self
 9996            .language_server_statuses
 9997            .remove(&server_id)
 9998            .map(|status| status.name)
 9999            .or_else(|| {
10000                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10001                    Some(adapter.name())
10002                } else {
10003                    None
10004                }
10005            });
10006
10007        if let Some(name) = name {
10008            log::info!("stopping language server {name}");
10009            self.languages
10010                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10011            cx.notify();
10012
10013            return cx.spawn(async move |lsp_store, cx| {
10014                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10015                lsp_store
10016                    .update(cx, |lsp_store, cx| {
10017                        lsp_store
10018                            .languages
10019                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10020                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10021                        cx.notify();
10022                    })
10023                    .ok();
10024            });
10025        }
10026
10027        if server_state.is_some() {
10028            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10029        }
10030        Task::ready(())
10031    }
10032
10033    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10034        if let Some((client, project_id)) = self.upstream_client() {
10035            let request = client.request(proto::StopLanguageServers {
10036                project_id,
10037                buffer_ids: Vec::new(),
10038                also_servers: Vec::new(),
10039                all: true,
10040            });
10041            cx.background_spawn(request).detach_and_log_err(cx);
10042        } else {
10043            let Some(local) = self.as_local_mut() else {
10044                return;
10045            };
10046            let language_servers_to_stop = local
10047                .language_server_ids
10048                .values()
10049                .map(|state| state.id)
10050                .collect();
10051            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10052            let tasks = language_servers_to_stop
10053                .into_iter()
10054                .map(|server| self.stop_local_language_server(server, cx))
10055                .collect::<Vec<_>>();
10056            cx.background_spawn(async move {
10057                futures::future::join_all(tasks).await;
10058            })
10059            .detach();
10060        }
10061    }
10062
10063    pub fn restart_language_servers_for_buffers(
10064        &mut self,
10065        buffers: Vec<Entity<Buffer>>,
10066        only_restart_servers: HashSet<LanguageServerSelector>,
10067        cx: &mut Context<Self>,
10068    ) {
10069        if let Some((client, project_id)) = self.upstream_client() {
10070            let request = client.request(proto::RestartLanguageServers {
10071                project_id,
10072                buffer_ids: buffers
10073                    .into_iter()
10074                    .map(|b| b.read(cx).remote_id().to_proto())
10075                    .collect(),
10076                only_servers: only_restart_servers
10077                    .into_iter()
10078                    .map(|selector| {
10079                        let selector = match selector {
10080                            LanguageServerSelector::Id(language_server_id) => {
10081                                proto::language_server_selector::Selector::ServerId(
10082                                    language_server_id.to_proto(),
10083                                )
10084                            }
10085                            LanguageServerSelector::Name(language_server_name) => {
10086                                proto::language_server_selector::Selector::Name(
10087                                    language_server_name.to_string(),
10088                                )
10089                            }
10090                        };
10091                        proto::LanguageServerSelector {
10092                            selector: Some(selector),
10093                        }
10094                    })
10095                    .collect(),
10096                all: false,
10097            });
10098            cx.background_spawn(request).detach_and_log_err(cx);
10099        } else {
10100            let stop_task = if only_restart_servers.is_empty() {
10101                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10102            } else {
10103                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10104            };
10105            cx.spawn(async move |lsp_store, cx| {
10106                stop_task.await;
10107                lsp_store
10108                    .update(cx, |lsp_store, cx| {
10109                        for buffer in buffers {
10110                            lsp_store.register_buffer_with_language_servers(
10111                                &buffer,
10112                                only_restart_servers.clone(),
10113                                true,
10114                                cx,
10115                            );
10116                        }
10117                    })
10118                    .ok()
10119            })
10120            .detach();
10121        }
10122    }
10123
10124    pub fn stop_language_servers_for_buffers(
10125        &mut self,
10126        buffers: Vec<Entity<Buffer>>,
10127        also_stop_servers: HashSet<LanguageServerSelector>,
10128        cx: &mut Context<Self>,
10129    ) -> Task<Result<()>> {
10130        if let Some((client, project_id)) = self.upstream_client() {
10131            let request = client.request(proto::StopLanguageServers {
10132                project_id,
10133                buffer_ids: buffers
10134                    .into_iter()
10135                    .map(|b| b.read(cx).remote_id().to_proto())
10136                    .collect(),
10137                also_servers: also_stop_servers
10138                    .into_iter()
10139                    .map(|selector| {
10140                        let selector = match selector {
10141                            LanguageServerSelector::Id(language_server_id) => {
10142                                proto::language_server_selector::Selector::ServerId(
10143                                    language_server_id.to_proto(),
10144                                )
10145                            }
10146                            LanguageServerSelector::Name(language_server_name) => {
10147                                proto::language_server_selector::Selector::Name(
10148                                    language_server_name.to_string(),
10149                                )
10150                            }
10151                        };
10152                        proto::LanguageServerSelector {
10153                            selector: Some(selector),
10154                        }
10155                    })
10156                    .collect(),
10157                all: false,
10158            });
10159            cx.background_spawn(async move {
10160                let _ = request.await?;
10161                Ok(())
10162            })
10163        } else {
10164            let task =
10165                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10166            cx.background_spawn(async move {
10167                task.await;
10168                Ok(())
10169            })
10170        }
10171    }
10172
10173    fn stop_local_language_servers_for_buffers(
10174        &mut self,
10175        buffers: &[Entity<Buffer>],
10176        also_stop_servers: HashSet<LanguageServerSelector>,
10177        cx: &mut Context<Self>,
10178    ) -> Task<()> {
10179        let Some(local) = self.as_local_mut() else {
10180            return Task::ready(());
10181        };
10182        let mut language_server_names_to_stop = BTreeSet::default();
10183        let mut language_servers_to_stop = also_stop_servers
10184            .into_iter()
10185            .flat_map(|selector| match selector {
10186                LanguageServerSelector::Id(id) => Some(id),
10187                LanguageServerSelector::Name(name) => {
10188                    language_server_names_to_stop.insert(name);
10189                    None
10190                }
10191            })
10192            .collect::<BTreeSet<_>>();
10193
10194        let mut covered_worktrees = HashSet::default();
10195        for buffer in buffers {
10196            buffer.update(cx, |buffer, cx| {
10197                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10198                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10199                    && covered_worktrees.insert(worktree_id)
10200                {
10201                    language_server_names_to_stop.retain(|name| {
10202                        let old_ids_count = language_servers_to_stop.len();
10203                        let all_language_servers_with_this_name = local
10204                            .language_server_ids
10205                            .iter()
10206                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10207                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10208                        old_ids_count == language_servers_to_stop.len()
10209                    });
10210                }
10211            });
10212        }
10213        for name in language_server_names_to_stop {
10214            language_servers_to_stop.extend(
10215                local
10216                    .language_server_ids
10217                    .iter()
10218                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10219            );
10220        }
10221
10222        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10223        let tasks = language_servers_to_stop
10224            .into_iter()
10225            .map(|server| self.stop_local_language_server(server, cx))
10226            .collect::<Vec<_>>();
10227
10228        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10229    }
10230
10231    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10232        let (worktree, relative_path) =
10233            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10234
10235        let project_path = ProjectPath {
10236            worktree_id: worktree.read(cx).id(),
10237            path: relative_path.into(),
10238        };
10239
10240        Some(
10241            self.buffer_store()
10242                .read(cx)
10243                .get_by_path(&project_path)?
10244                .read(cx),
10245        )
10246    }
10247
10248    #[cfg(any(test, feature = "test-support"))]
10249    pub fn update_diagnostics(
10250        &mut self,
10251        server_id: LanguageServerId,
10252        diagnostics: lsp::PublishDiagnosticsParams,
10253        result_id: Option<String>,
10254        source_kind: DiagnosticSourceKind,
10255        disk_based_sources: &[String],
10256        cx: &mut Context<Self>,
10257    ) -> Result<()> {
10258        self.merge_lsp_diagnostics(
10259            source_kind,
10260            vec![DocumentDiagnosticsUpdate {
10261                diagnostics,
10262                result_id,
10263                server_id,
10264                disk_based_sources: Cow::Borrowed(disk_based_sources),
10265            }],
10266            |_, _, _| false,
10267            cx,
10268        )
10269    }
10270
10271    pub fn merge_lsp_diagnostics(
10272        &mut self,
10273        source_kind: DiagnosticSourceKind,
10274        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10275        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10276        cx: &mut Context<Self>,
10277    ) -> Result<()> {
10278        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10279        let updates = lsp_diagnostics
10280            .into_iter()
10281            .filter_map(|update| {
10282                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10283                Some(DocumentDiagnosticsUpdate {
10284                    diagnostics: self.lsp_to_document_diagnostics(
10285                        abs_path,
10286                        source_kind,
10287                        update.server_id,
10288                        update.diagnostics,
10289                        &update.disk_based_sources,
10290                    ),
10291                    result_id: update.result_id,
10292                    server_id: update.server_id,
10293                    disk_based_sources: update.disk_based_sources,
10294                })
10295            })
10296            .collect();
10297        self.merge_diagnostic_entries(updates, merge, cx)?;
10298        Ok(())
10299    }
10300
10301    fn lsp_to_document_diagnostics(
10302        &mut self,
10303        document_abs_path: PathBuf,
10304        source_kind: DiagnosticSourceKind,
10305        server_id: LanguageServerId,
10306        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10307        disk_based_sources: &[String],
10308    ) -> DocumentDiagnostics {
10309        let mut diagnostics = Vec::default();
10310        let mut primary_diagnostic_group_ids = HashMap::default();
10311        let mut sources_by_group_id = HashMap::default();
10312        let mut supporting_diagnostics = HashMap::default();
10313
10314        let adapter = self.language_server_adapter_for_id(server_id);
10315
10316        // Ensure that primary diagnostics are always the most severe
10317        lsp_diagnostics
10318            .diagnostics
10319            .sort_by_key(|item| item.severity);
10320
10321        for diagnostic in &lsp_diagnostics.diagnostics {
10322            let source = diagnostic.source.as_ref();
10323            let range = range_from_lsp(diagnostic.range);
10324            let is_supporting = diagnostic
10325                .related_information
10326                .as_ref()
10327                .is_some_and(|infos| {
10328                    infos.iter().any(|info| {
10329                        primary_diagnostic_group_ids.contains_key(&(
10330                            source,
10331                            diagnostic.code.clone(),
10332                            range_from_lsp(info.location.range),
10333                        ))
10334                    })
10335                });
10336
10337            let is_unnecessary = diagnostic
10338                .tags
10339                .as_ref()
10340                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10341
10342            let underline = self
10343                .language_server_adapter_for_id(server_id)
10344                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10345
10346            if is_supporting {
10347                supporting_diagnostics.insert(
10348                    (source, diagnostic.code.clone(), range),
10349                    (diagnostic.severity, is_unnecessary),
10350                );
10351            } else {
10352                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10353                let is_disk_based =
10354                    source.is_some_and(|source| disk_based_sources.contains(source));
10355
10356                sources_by_group_id.insert(group_id, source);
10357                primary_diagnostic_group_ids
10358                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10359
10360                diagnostics.push(DiagnosticEntry {
10361                    range,
10362                    diagnostic: Diagnostic {
10363                        source: diagnostic.source.clone(),
10364                        source_kind,
10365                        code: diagnostic.code.clone(),
10366                        code_description: diagnostic
10367                            .code_description
10368                            .as_ref()
10369                            .and_then(|d| d.href.clone()),
10370                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10371                        markdown: adapter.as_ref().and_then(|adapter| {
10372                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10373                        }),
10374                        message: diagnostic.message.trim().to_string(),
10375                        group_id,
10376                        is_primary: true,
10377                        is_disk_based,
10378                        is_unnecessary,
10379                        underline,
10380                        data: diagnostic.data.clone(),
10381                    },
10382                });
10383                if let Some(infos) = &diagnostic.related_information {
10384                    for info in infos {
10385                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10386                            let range = range_from_lsp(info.location.range);
10387                            diagnostics.push(DiagnosticEntry {
10388                                range,
10389                                diagnostic: Diagnostic {
10390                                    source: diagnostic.source.clone(),
10391                                    source_kind,
10392                                    code: diagnostic.code.clone(),
10393                                    code_description: diagnostic
10394                                        .code_description
10395                                        .as_ref()
10396                                        .and_then(|d| d.href.clone()),
10397                                    severity: DiagnosticSeverity::INFORMATION,
10398                                    markdown: adapter.as_ref().and_then(|adapter| {
10399                                        adapter.diagnostic_message_to_markdown(&info.message)
10400                                    }),
10401                                    message: info.message.trim().to_string(),
10402                                    group_id,
10403                                    is_primary: false,
10404                                    is_disk_based,
10405                                    is_unnecessary: false,
10406                                    underline,
10407                                    data: diagnostic.data.clone(),
10408                                },
10409                            });
10410                        }
10411                    }
10412                }
10413            }
10414        }
10415
10416        for entry in &mut diagnostics {
10417            let diagnostic = &mut entry.diagnostic;
10418            if !diagnostic.is_primary {
10419                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10420                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10421                    source,
10422                    diagnostic.code.clone(),
10423                    entry.range.clone(),
10424                )) {
10425                    if let Some(severity) = severity {
10426                        diagnostic.severity = severity;
10427                    }
10428                    diagnostic.is_unnecessary = is_unnecessary;
10429                }
10430            }
10431        }
10432
10433        DocumentDiagnostics {
10434            diagnostics,
10435            document_abs_path,
10436            version: lsp_diagnostics.version,
10437        }
10438    }
10439
10440    fn insert_newly_running_language_server(
10441        &mut self,
10442        adapter: Arc<CachedLspAdapter>,
10443        language_server: Arc<LanguageServer>,
10444        server_id: LanguageServerId,
10445        key: LanguageServerSeed,
10446        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10447        cx: &mut Context<Self>,
10448    ) {
10449        let Some(local) = self.as_local_mut() else {
10450            return;
10451        };
10452        // If the language server for this key doesn't match the server id, don't store the
10453        // server. Which will cause it to be dropped, killing the process
10454        if local
10455            .language_server_ids
10456            .get(&key)
10457            .map(|state| state.id != server_id)
10458            .unwrap_or(false)
10459        {
10460            return;
10461        }
10462
10463        // Update language_servers collection with Running variant of LanguageServerState
10464        // indicating that the server is up and running and ready
10465        let workspace_folders = workspace_folders.lock().clone();
10466        language_server.set_workspace_folders(workspace_folders);
10467
10468        local.language_servers.insert(
10469            server_id,
10470            LanguageServerState::Running {
10471                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10472                    language_server.clone(),
10473                    cx,
10474                ),
10475                adapter: adapter.clone(),
10476                server: language_server.clone(),
10477                simulate_disk_based_diagnostics_completion: None,
10478            },
10479        );
10480        local
10481            .languages
10482            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10483        if let Some(file_ops_caps) = language_server
10484            .capabilities()
10485            .workspace
10486            .as_ref()
10487            .and_then(|ws| ws.file_operations.as_ref())
10488        {
10489            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10490            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10491            if did_rename_caps.or(will_rename_caps).is_some() {
10492                let watcher = RenamePathsWatchedForServer::default()
10493                    .with_did_rename_patterns(did_rename_caps)
10494                    .with_will_rename_patterns(will_rename_caps);
10495                local
10496                    .language_server_paths_watched_for_rename
10497                    .insert(server_id, watcher);
10498            }
10499        }
10500
10501        self.language_server_statuses.insert(
10502            server_id,
10503            LanguageServerStatus {
10504                name: language_server.name(),
10505                pending_work: Default::default(),
10506                has_pending_diagnostic_updates: false,
10507                progress_tokens: Default::default(),
10508                worktree: Some(key.worktree_id),
10509            },
10510        );
10511
10512        cx.emit(LspStoreEvent::LanguageServerAdded(
10513            server_id,
10514            language_server.name(),
10515            Some(key.worktree_id),
10516        ));
10517        cx.emit(LspStoreEvent::RefreshInlayHints);
10518
10519        let server_capabilities = language_server.capabilities();
10520        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10521            downstream_client
10522                .send(proto::StartLanguageServer {
10523                    project_id: *project_id,
10524                    server: Some(proto::LanguageServer {
10525                        id: server_id.to_proto(),
10526                        name: language_server.name().to_string(),
10527                        worktree_id: Some(key.worktree_id.to_proto()),
10528                    }),
10529                    capabilities: serde_json::to_string(&server_capabilities)
10530                        .expect("serializing server LSP capabilities"),
10531                })
10532                .log_err();
10533        }
10534        self.lsp_server_capabilities
10535            .insert(server_id, server_capabilities);
10536
10537        // Tell the language server about every open buffer in the worktree that matches the language.
10538        // Also check for buffers in worktrees that reused this server
10539        let mut worktrees_using_server = vec![key.worktree_id];
10540        if let Some(local) = self.as_local() {
10541            // Find all worktrees that have this server in their language server tree
10542            for (worktree_id, servers) in &local.lsp_tree.instances {
10543                if *worktree_id != key.worktree_id {
10544                    for server_map in servers.roots.values() {
10545                        if server_map.contains_key(&key.name) {
10546                            worktrees_using_server.push(*worktree_id);
10547                        }
10548                    }
10549                }
10550            }
10551        }
10552
10553        let mut buffer_paths_registered = Vec::new();
10554        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10555            for buffer_handle in buffer_store.buffers() {
10556                let buffer = buffer_handle.read(cx);
10557                let file = match File::from_dyn(buffer.file()) {
10558                    Some(file) => file,
10559                    None => continue,
10560                };
10561                let language = match buffer.language() {
10562                    Some(language) => language,
10563                    None => continue,
10564                };
10565
10566                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10567                    || !self
10568                        .languages
10569                        .lsp_adapters(&language.name())
10570                        .iter()
10571                        .any(|a| a.name == key.name)
10572                {
10573                    continue;
10574                }
10575                // didOpen
10576                let file = match file.as_local() {
10577                    Some(file) => file,
10578                    None => continue,
10579                };
10580
10581                let local = self.as_local_mut().unwrap();
10582
10583                let buffer_id = buffer.remote_id();
10584                if local.registered_buffers.contains_key(&buffer_id) {
10585                    let versions = local
10586                        .buffer_snapshots
10587                        .entry(buffer_id)
10588                        .or_default()
10589                        .entry(server_id)
10590                        .and_modify(|_| {
10591                            assert!(
10592                            false,
10593                            "There should not be an existing snapshot for a newly inserted buffer"
10594                        )
10595                        })
10596                        .or_insert_with(|| {
10597                            vec![LspBufferSnapshot {
10598                                version: 0,
10599                                snapshot: buffer.text_snapshot(),
10600                            }]
10601                        });
10602
10603                    let snapshot = versions.last().unwrap();
10604                    let version = snapshot.version;
10605                    let initial_snapshot = &snapshot.snapshot;
10606                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
10607                    language_server.register_buffer(
10608                        uri,
10609                        adapter.language_id(&language.name()),
10610                        version,
10611                        initial_snapshot.text(),
10612                    );
10613                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
10614                    local
10615                        .buffers_opened_in_servers
10616                        .entry(buffer_id)
10617                        .or_default()
10618                        .insert(server_id);
10619                }
10620                buffer_handle.update(cx, |buffer, cx| {
10621                    buffer.set_completion_triggers(
10622                        server_id,
10623                        language_server
10624                            .capabilities()
10625                            .completion_provider
10626                            .as_ref()
10627                            .and_then(|provider| {
10628                                provider
10629                                    .trigger_characters
10630                                    .as_ref()
10631                                    .map(|characters| characters.iter().cloned().collect())
10632                            })
10633                            .unwrap_or_default(),
10634                        cx,
10635                    )
10636                });
10637            }
10638        });
10639
10640        for (buffer_id, abs_path) in buffer_paths_registered {
10641            cx.emit(LspStoreEvent::LanguageServerUpdate {
10642                language_server_id: server_id,
10643                name: Some(adapter.name()),
10644                message: proto::update_language_server::Variant::RegisteredForBuffer(
10645                    proto::RegisteredForBuffer {
10646                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
10647                        buffer_id: buffer_id.to_proto(),
10648                    },
10649                ),
10650            });
10651        }
10652
10653        cx.notify();
10654    }
10655
10656    pub fn language_servers_running_disk_based_diagnostics(
10657        &self,
10658    ) -> impl Iterator<Item = LanguageServerId> + '_ {
10659        self.language_server_statuses
10660            .iter()
10661            .filter_map(|(id, status)| {
10662                if status.has_pending_diagnostic_updates {
10663                    Some(*id)
10664                } else {
10665                    None
10666                }
10667            })
10668    }
10669
10670    pub(crate) fn cancel_language_server_work_for_buffers(
10671        &mut self,
10672        buffers: impl IntoIterator<Item = Entity<Buffer>>,
10673        cx: &mut Context<Self>,
10674    ) {
10675        if let Some((client, project_id)) = self.upstream_client() {
10676            let request = client.request(proto::CancelLanguageServerWork {
10677                project_id,
10678                work: Some(proto::cancel_language_server_work::Work::Buffers(
10679                    proto::cancel_language_server_work::Buffers {
10680                        buffer_ids: buffers
10681                            .into_iter()
10682                            .map(|b| b.read(cx).remote_id().to_proto())
10683                            .collect(),
10684                    },
10685                )),
10686            });
10687            cx.background_spawn(request).detach_and_log_err(cx);
10688        } else if let Some(local) = self.as_local() {
10689            let servers = buffers
10690                .into_iter()
10691                .flat_map(|buffer| {
10692                    buffer.update(cx, |buffer, cx| {
10693                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
10694                    })
10695                })
10696                .collect::<HashSet<_>>();
10697            for server_id in servers {
10698                self.cancel_language_server_work(server_id, None, cx);
10699            }
10700        }
10701    }
10702
10703    pub(crate) fn cancel_language_server_work(
10704        &mut self,
10705        server_id: LanguageServerId,
10706        token_to_cancel: Option<String>,
10707        cx: &mut Context<Self>,
10708    ) {
10709        if let Some(local) = self.as_local() {
10710            let status = self.language_server_statuses.get(&server_id);
10711            let server = local.language_servers.get(&server_id);
10712            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
10713            {
10714                for (token, progress) in &status.pending_work {
10715                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
10716                        && token != token_to_cancel
10717                    {
10718                        continue;
10719                    }
10720                    if progress.is_cancellable {
10721                        server
10722                            .notify::<lsp::notification::WorkDoneProgressCancel>(
10723                                &WorkDoneProgressCancelParams {
10724                                    token: lsp::NumberOrString::String(token.clone()),
10725                                },
10726                            )
10727                            .ok();
10728                    }
10729                }
10730            }
10731        } else if let Some((client, project_id)) = self.upstream_client() {
10732            let request = client.request(proto::CancelLanguageServerWork {
10733                project_id,
10734                work: Some(
10735                    proto::cancel_language_server_work::Work::LanguageServerWork(
10736                        proto::cancel_language_server_work::LanguageServerWork {
10737                            language_server_id: server_id.to_proto(),
10738                            token: token_to_cancel,
10739                        },
10740                    ),
10741                ),
10742            });
10743            cx.background_spawn(request).detach_and_log_err(cx);
10744        }
10745    }
10746
10747    fn register_supplementary_language_server(
10748        &mut self,
10749        id: LanguageServerId,
10750        name: LanguageServerName,
10751        server: Arc<LanguageServer>,
10752        cx: &mut Context<Self>,
10753    ) {
10754        if let Some(local) = self.as_local_mut() {
10755            local
10756                .supplementary_language_servers
10757                .insert(id, (name.clone(), server));
10758            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
10759        }
10760    }
10761
10762    fn unregister_supplementary_language_server(
10763        &mut self,
10764        id: LanguageServerId,
10765        cx: &mut Context<Self>,
10766    ) {
10767        if let Some(local) = self.as_local_mut() {
10768            local.supplementary_language_servers.remove(&id);
10769            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
10770        }
10771    }
10772
10773    pub(crate) fn supplementary_language_servers(
10774        &self,
10775    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
10776        self.as_local().into_iter().flat_map(|local| {
10777            local
10778                .supplementary_language_servers
10779                .iter()
10780                .map(|(id, (name, _))| (*id, name.clone()))
10781        })
10782    }
10783
10784    pub fn language_server_adapter_for_id(
10785        &self,
10786        id: LanguageServerId,
10787    ) -> Option<Arc<CachedLspAdapter>> {
10788        self.as_local()
10789            .and_then(|local| local.language_servers.get(&id))
10790            .and_then(|language_server_state| match language_server_state {
10791                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
10792                _ => None,
10793            })
10794    }
10795
10796    pub(super) fn update_local_worktree_language_servers(
10797        &mut self,
10798        worktree_handle: &Entity<Worktree>,
10799        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
10800        cx: &mut Context<Self>,
10801    ) {
10802        if changes.is_empty() {
10803            return;
10804        }
10805
10806        let Some(local) = self.as_local() else { return };
10807
10808        local.prettier_store.update(cx, |prettier_store, cx| {
10809            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
10810        });
10811
10812        let worktree_id = worktree_handle.read(cx).id();
10813        let mut language_server_ids = local
10814            .language_server_ids
10815            .iter()
10816            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
10817            .collect::<Vec<_>>();
10818        language_server_ids.sort();
10819        language_server_ids.dedup();
10820
10821        let abs_path = worktree_handle.read(cx).abs_path();
10822        for server_id in &language_server_ids {
10823            if let Some(LanguageServerState::Running { server, .. }) =
10824                local.language_servers.get(server_id)
10825                && let Some(watched_paths) = local
10826                    .language_server_watched_paths
10827                    .get(server_id)
10828                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
10829            {
10830                let params = lsp::DidChangeWatchedFilesParams {
10831                    changes: changes
10832                        .iter()
10833                        .filter_map(|(path, _, change)| {
10834                            if !watched_paths.is_match(path) {
10835                                return None;
10836                            }
10837                            let typ = match change {
10838                                PathChange::Loaded => return None,
10839                                PathChange::Added => lsp::FileChangeType::CREATED,
10840                                PathChange::Removed => lsp::FileChangeType::DELETED,
10841                                PathChange::Updated => lsp::FileChangeType::CHANGED,
10842                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
10843                            };
10844                            Some(lsp::FileEvent {
10845                                uri: lsp::Uri::from_file_path(abs_path.join(path)).unwrap(),
10846                                typ,
10847                            })
10848                        })
10849                        .collect(),
10850                };
10851                if !params.changes.is_empty() {
10852                    server
10853                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
10854                        .ok();
10855                }
10856            }
10857        }
10858        for (path, _, _) in changes {
10859            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
10860                && local.watched_manifest_filenames.contains(file_name)
10861            {
10862                self.request_workspace_config_refresh();
10863                break;
10864            }
10865        }
10866    }
10867
10868    pub fn wait_for_remote_buffer(
10869        &mut self,
10870        id: BufferId,
10871        cx: &mut Context<Self>,
10872    ) -> Task<Result<Entity<Buffer>>> {
10873        self.buffer_store.update(cx, |buffer_store, cx| {
10874            buffer_store.wait_for_remote_buffer(id, cx)
10875        })
10876    }
10877
10878    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
10879        proto::Symbol {
10880            language_server_name: symbol.language_server_name.0.to_string(),
10881            source_worktree_id: symbol.source_worktree_id.to_proto(),
10882            language_server_id: symbol.source_language_server_id.to_proto(),
10883            worktree_id: symbol.path.worktree_id.to_proto(),
10884            path: symbol.path.path.as_ref().to_proto(),
10885            name: symbol.name.clone(),
10886            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
10887            start: Some(proto::PointUtf16 {
10888                row: symbol.range.start.0.row,
10889                column: symbol.range.start.0.column,
10890            }),
10891            end: Some(proto::PointUtf16 {
10892                row: symbol.range.end.0.row,
10893                column: symbol.range.end.0.column,
10894            }),
10895            signature: symbol.signature.to_vec(),
10896        }
10897    }
10898
10899    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
10900        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
10901        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
10902        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
10903        let path = ProjectPath {
10904            worktree_id,
10905            path: Arc::<Path>::from_proto(serialized_symbol.path),
10906        };
10907
10908        let start = serialized_symbol.start.context("invalid start")?;
10909        let end = serialized_symbol.end.context("invalid end")?;
10910        Ok(CoreSymbol {
10911            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
10912            source_worktree_id,
10913            source_language_server_id: LanguageServerId::from_proto(
10914                serialized_symbol.language_server_id,
10915            ),
10916            path,
10917            name: serialized_symbol.name,
10918            range: Unclipped(PointUtf16::new(start.row, start.column))
10919                ..Unclipped(PointUtf16::new(end.row, end.column)),
10920            kind,
10921            signature: serialized_symbol
10922                .signature
10923                .try_into()
10924                .map_err(|_| anyhow!("invalid signature"))?,
10925        })
10926    }
10927
10928    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
10929        let mut serialized_completion = proto::Completion {
10930            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
10931            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
10932            new_text: completion.new_text.clone(),
10933            ..proto::Completion::default()
10934        };
10935        match &completion.source {
10936            CompletionSource::Lsp {
10937                insert_range,
10938                server_id,
10939                lsp_completion,
10940                lsp_defaults,
10941                resolved,
10942            } => {
10943                let (old_insert_start, old_insert_end) = insert_range
10944                    .as_ref()
10945                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
10946                    .unzip();
10947
10948                serialized_completion.old_insert_start = old_insert_start;
10949                serialized_completion.old_insert_end = old_insert_end;
10950                serialized_completion.source = proto::completion::Source::Lsp as i32;
10951                serialized_completion.server_id = server_id.0 as u64;
10952                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
10953                serialized_completion.lsp_defaults = lsp_defaults
10954                    .as_deref()
10955                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
10956                serialized_completion.resolved = *resolved;
10957            }
10958            CompletionSource::BufferWord {
10959                word_range,
10960                resolved,
10961            } => {
10962                serialized_completion.source = proto::completion::Source::BufferWord as i32;
10963                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
10964                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
10965                serialized_completion.resolved = *resolved;
10966            }
10967            CompletionSource::Custom => {
10968                serialized_completion.source = proto::completion::Source::Custom as i32;
10969                serialized_completion.resolved = true;
10970            }
10971            CompletionSource::Dap { sort_text } => {
10972                serialized_completion.source = proto::completion::Source::Dap as i32;
10973                serialized_completion.sort_text = Some(sort_text.clone());
10974            }
10975        }
10976
10977        serialized_completion
10978    }
10979
10980    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
10981        let old_replace_start = completion
10982            .old_replace_start
10983            .and_then(deserialize_anchor)
10984            .context("invalid old start")?;
10985        let old_replace_end = completion
10986            .old_replace_end
10987            .and_then(deserialize_anchor)
10988            .context("invalid old end")?;
10989        let insert_range = {
10990            match completion.old_insert_start.zip(completion.old_insert_end) {
10991                Some((start, end)) => {
10992                    let start = deserialize_anchor(start).context("invalid insert old start")?;
10993                    let end = deserialize_anchor(end).context("invalid insert old end")?;
10994                    Some(start..end)
10995                }
10996                None => None,
10997            }
10998        };
10999        Ok(CoreCompletion {
11000            replace_range: old_replace_start..old_replace_end,
11001            new_text: completion.new_text,
11002            source: match proto::completion::Source::from_i32(completion.source) {
11003                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11004                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11005                    insert_range,
11006                    server_id: LanguageServerId::from_proto(completion.server_id),
11007                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11008                    lsp_defaults: completion
11009                        .lsp_defaults
11010                        .as_deref()
11011                        .map(serde_json::from_slice)
11012                        .transpose()?,
11013                    resolved: completion.resolved,
11014                },
11015                Some(proto::completion::Source::BufferWord) => {
11016                    let word_range = completion
11017                        .buffer_word_start
11018                        .and_then(deserialize_anchor)
11019                        .context("invalid buffer word start")?
11020                        ..completion
11021                            .buffer_word_end
11022                            .and_then(deserialize_anchor)
11023                            .context("invalid buffer word end")?;
11024                    CompletionSource::BufferWord {
11025                        word_range,
11026                        resolved: completion.resolved,
11027                    }
11028                }
11029                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11030                    sort_text: completion
11031                        .sort_text
11032                        .context("expected sort text to exist")?,
11033                },
11034                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11035            },
11036        })
11037    }
11038
11039    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11040        let (kind, lsp_action) = match &action.lsp_action {
11041            LspAction::Action(code_action) => (
11042                proto::code_action::Kind::Action as i32,
11043                serde_json::to_vec(code_action).unwrap(),
11044            ),
11045            LspAction::Command(command) => (
11046                proto::code_action::Kind::Command as i32,
11047                serde_json::to_vec(command).unwrap(),
11048            ),
11049            LspAction::CodeLens(code_lens) => (
11050                proto::code_action::Kind::CodeLens as i32,
11051                serde_json::to_vec(code_lens).unwrap(),
11052            ),
11053        };
11054
11055        proto::CodeAction {
11056            server_id: action.server_id.0 as u64,
11057            start: Some(serialize_anchor(&action.range.start)),
11058            end: Some(serialize_anchor(&action.range.end)),
11059            lsp_action,
11060            kind,
11061            resolved: action.resolved,
11062        }
11063    }
11064
11065    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11066        let start = action
11067            .start
11068            .and_then(deserialize_anchor)
11069            .context("invalid start")?;
11070        let end = action
11071            .end
11072            .and_then(deserialize_anchor)
11073            .context("invalid end")?;
11074        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11075            Some(proto::code_action::Kind::Action) => {
11076                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11077            }
11078            Some(proto::code_action::Kind::Command) => {
11079                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11080            }
11081            Some(proto::code_action::Kind::CodeLens) => {
11082                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11083            }
11084            None => anyhow::bail!("Unknown action kind {}", action.kind),
11085        };
11086        Ok(CodeAction {
11087            server_id: LanguageServerId(action.server_id as usize),
11088            range: start..end,
11089            resolved: action.resolved,
11090            lsp_action,
11091        })
11092    }
11093
11094    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11095        match &formatting_result {
11096            Ok(_) => self.last_formatting_failure = None,
11097            Err(error) => {
11098                let error_string = format!("{error:#}");
11099                log::error!("Formatting failed: {error_string}");
11100                self.last_formatting_failure
11101                    .replace(error_string.lines().join(" "));
11102            }
11103        }
11104    }
11105
11106    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11107        self.lsp_server_capabilities.remove(&for_server);
11108        for buffer_colors in self.lsp_document_colors.values_mut() {
11109            buffer_colors.colors.remove(&for_server);
11110            buffer_colors.cache_version += 1;
11111        }
11112        for buffer_lens in self.lsp_code_lens.values_mut() {
11113            buffer_lens.lens.remove(&for_server);
11114        }
11115        if let Some(local) = self.as_local_mut() {
11116            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11117            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11118                buffer_servers.remove(&for_server);
11119            }
11120        }
11121    }
11122
11123    pub fn result_id(
11124        &self,
11125        server_id: LanguageServerId,
11126        buffer_id: BufferId,
11127        cx: &App,
11128    ) -> Option<String> {
11129        let abs_path = self
11130            .buffer_store
11131            .read(cx)
11132            .get(buffer_id)
11133            .and_then(|b| File::from_dyn(b.read(cx).file()))
11134            .map(|f| f.abs_path(cx))?;
11135        self.as_local()?
11136            .buffer_pull_diagnostics_result_ids
11137            .get(&server_id)?
11138            .get(&abs_path)?
11139            .clone()
11140    }
11141
11142    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11143        let Some(local) = self.as_local() else {
11144            return HashMap::default();
11145        };
11146        local
11147            .buffer_pull_diagnostics_result_ids
11148            .get(&server_id)
11149            .into_iter()
11150            .flatten()
11151            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11152            .collect()
11153    }
11154
11155    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11156        if let Some(LanguageServerState::Running {
11157            workspace_refresh_task: Some(workspace_refresh_task),
11158            ..
11159        }) = self
11160            .as_local_mut()
11161            .and_then(|local| local.language_servers.get_mut(&server_id))
11162        {
11163            workspace_refresh_task.refresh_tx.try_send(()).ok();
11164        }
11165    }
11166
11167    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11168        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11169            return;
11170        };
11171        let Some(local) = self.as_local_mut() else {
11172            return;
11173        };
11174
11175        for server_id in buffer.update(cx, |buffer, cx| {
11176            local.language_server_ids_for_buffer(buffer, cx)
11177        }) {
11178            if let Some(LanguageServerState::Running {
11179                workspace_refresh_task: Some(workspace_refresh_task),
11180                ..
11181            }) = local.language_servers.get_mut(&server_id)
11182            {
11183                workspace_refresh_task.refresh_tx.try_send(()).ok();
11184            }
11185        }
11186    }
11187
11188    fn apply_workspace_diagnostic_report(
11189        &mut self,
11190        server_id: LanguageServerId,
11191        report: lsp::WorkspaceDiagnosticReportResult,
11192        cx: &mut Context<Self>,
11193    ) {
11194        let workspace_diagnostics =
11195            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11196        let mut unchanged_buffers = HashSet::default();
11197        let mut changed_buffers = HashSet::default();
11198        let workspace_diagnostics_updates = workspace_diagnostics
11199            .into_iter()
11200            .filter_map(
11201                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11202                    LspPullDiagnostics::Response {
11203                        server_id,
11204                        uri,
11205                        diagnostics,
11206                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11207                    LspPullDiagnostics::Default => None,
11208                },
11209            )
11210            .fold(
11211                HashMap::default(),
11212                |mut acc, (server_id, uri, diagnostics, version)| {
11213                    let (result_id, diagnostics) = match diagnostics {
11214                        PulledDiagnostics::Unchanged { result_id } => {
11215                            unchanged_buffers.insert(uri.clone());
11216                            (Some(result_id), Vec::new())
11217                        }
11218                        PulledDiagnostics::Changed {
11219                            result_id,
11220                            diagnostics,
11221                        } => {
11222                            changed_buffers.insert(uri.clone());
11223                            (result_id, diagnostics)
11224                        }
11225                    };
11226                    let disk_based_sources = Cow::Owned(
11227                        self.language_server_adapter_for_id(server_id)
11228                            .as_ref()
11229                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11230                            .unwrap_or(&[])
11231                            .to_vec(),
11232                    );
11233                    acc.entry(server_id)
11234                        .or_insert_with(Vec::new)
11235                        .push(DocumentDiagnosticsUpdate {
11236                            server_id,
11237                            diagnostics: lsp::PublishDiagnosticsParams {
11238                                uri,
11239                                diagnostics,
11240                                version,
11241                            },
11242                            result_id,
11243                            disk_based_sources,
11244                        });
11245                    acc
11246                },
11247            );
11248
11249        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11250            self.merge_lsp_diagnostics(
11251                DiagnosticSourceKind::Pulled,
11252                diagnostic_updates,
11253                |buffer, old_diagnostic, cx| {
11254                    File::from_dyn(buffer.file())
11255                        .and_then(|file| {
11256                            let abs_path = file.as_local()?.abs_path(cx);
11257                            lsp::Uri::from_file_path(abs_path).ok()
11258                        })
11259                        .is_none_or(|buffer_uri| {
11260                            unchanged_buffers.contains(&buffer_uri)
11261                                || match old_diagnostic.source_kind {
11262                                    DiagnosticSourceKind::Pulled => {
11263                                        !changed_buffers.contains(&buffer_uri)
11264                                    }
11265                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11266                                        true
11267                                    }
11268                                }
11269                        })
11270                },
11271                cx,
11272            )
11273            .log_err();
11274        }
11275    }
11276
11277    fn register_server_capabilities(
11278        &mut self,
11279        server_id: LanguageServerId,
11280        params: lsp::RegistrationParams,
11281        cx: &mut Context<Self>,
11282    ) -> anyhow::Result<()> {
11283        let server = self
11284            .language_server_for_id(server_id)
11285            .with_context(|| format!("no server {server_id} found"))?;
11286        for reg in params.registrations {
11287            match reg.method.as_str() {
11288                "workspace/didChangeWatchedFiles" => {
11289                    if let Some(options) = reg.register_options {
11290                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11291                            let caps = serde_json::from_value(options)?;
11292                            local_lsp_store
11293                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11294                            true
11295                        } else {
11296                            false
11297                        };
11298                        if notify {
11299                            notify_server_capabilities_updated(&server, cx);
11300                        }
11301                    }
11302                }
11303                "workspace/didChangeConfiguration" => {
11304                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11305                }
11306                "workspace/didChangeWorkspaceFolders" => {
11307                    // In this case register options is an empty object, we can ignore it
11308                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11309                        supported: Some(true),
11310                        change_notifications: Some(OneOf::Right(reg.id)),
11311                    };
11312                    server.update_capabilities(|capabilities| {
11313                        capabilities
11314                            .workspace
11315                            .get_or_insert_default()
11316                            .workspace_folders = Some(caps);
11317                    });
11318                    notify_server_capabilities_updated(&server, cx);
11319                }
11320                "workspace/symbol" => {
11321                    let options = parse_register_capabilities(reg)?;
11322                    server.update_capabilities(|capabilities| {
11323                        capabilities.workspace_symbol_provider = Some(options);
11324                    });
11325                    notify_server_capabilities_updated(&server, cx);
11326                }
11327                "workspace/fileOperations" => {
11328                    if let Some(options) = reg.register_options {
11329                        let caps = serde_json::from_value(options)?;
11330                        server.update_capabilities(|capabilities| {
11331                            capabilities
11332                                .workspace
11333                                .get_or_insert_default()
11334                                .file_operations = Some(caps);
11335                        });
11336                        notify_server_capabilities_updated(&server, cx);
11337                    }
11338                }
11339                "workspace/executeCommand" => {
11340                    if let Some(options) = reg.register_options {
11341                        let options = serde_json::from_value(options)?;
11342                        server.update_capabilities(|capabilities| {
11343                            capabilities.execute_command_provider = Some(options);
11344                        });
11345                        notify_server_capabilities_updated(&server, cx);
11346                    }
11347                }
11348                "textDocument/rangeFormatting" => {
11349                    let options = parse_register_capabilities(reg)?;
11350                    server.update_capabilities(|capabilities| {
11351                        capabilities.document_range_formatting_provider = Some(options);
11352                    });
11353                    notify_server_capabilities_updated(&server, cx);
11354                }
11355                "textDocument/onTypeFormatting" => {
11356                    if let Some(options) = reg
11357                        .register_options
11358                        .map(serde_json::from_value)
11359                        .transpose()?
11360                    {
11361                        server.update_capabilities(|capabilities| {
11362                            capabilities.document_on_type_formatting_provider = Some(options);
11363                        });
11364                        notify_server_capabilities_updated(&server, cx);
11365                    }
11366                }
11367                "textDocument/formatting" => {
11368                    let options = parse_register_capabilities(reg)?;
11369                    server.update_capabilities(|capabilities| {
11370                        capabilities.document_formatting_provider = Some(options);
11371                    });
11372                    notify_server_capabilities_updated(&server, cx);
11373                }
11374                "textDocument/rename" => {
11375                    let options = parse_register_capabilities(reg)?;
11376                    server.update_capabilities(|capabilities| {
11377                        capabilities.rename_provider = Some(options);
11378                    });
11379                    notify_server_capabilities_updated(&server, cx);
11380                }
11381                "textDocument/inlayHint" => {
11382                    let options = parse_register_capabilities(reg)?;
11383                    server.update_capabilities(|capabilities| {
11384                        capabilities.inlay_hint_provider = Some(options);
11385                    });
11386                    notify_server_capabilities_updated(&server, cx);
11387                }
11388                "textDocument/documentSymbol" => {
11389                    let options = parse_register_capabilities(reg)?;
11390                    server.update_capabilities(|capabilities| {
11391                        capabilities.document_symbol_provider = Some(options);
11392                    });
11393                    notify_server_capabilities_updated(&server, cx);
11394                }
11395                "textDocument/codeAction" => {
11396                    let options = parse_register_capabilities(reg)?;
11397                    let provider = match options {
11398                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11399                        OneOf::Right(caps) => caps,
11400                    };
11401                    server.update_capabilities(|capabilities| {
11402                        capabilities.code_action_provider = Some(provider);
11403                    });
11404                    notify_server_capabilities_updated(&server, cx);
11405                }
11406                "textDocument/definition" => {
11407                    let options = parse_register_capabilities(reg)?;
11408                    server.update_capabilities(|capabilities| {
11409                        capabilities.definition_provider = Some(options);
11410                    });
11411                    notify_server_capabilities_updated(&server, cx);
11412                }
11413                "textDocument/completion" => {
11414                    if let Some(caps) = reg
11415                        .register_options
11416                        .map(serde_json::from_value)
11417                        .transpose()?
11418                    {
11419                        server.update_capabilities(|capabilities| {
11420                            capabilities.completion_provider = Some(caps);
11421                        });
11422                        notify_server_capabilities_updated(&server, cx);
11423                    }
11424                }
11425                "textDocument/hover" => {
11426                    let options = parse_register_capabilities(reg)?;
11427                    let provider = match options {
11428                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11429                        OneOf::Right(caps) => caps,
11430                    };
11431                    server.update_capabilities(|capabilities| {
11432                        capabilities.hover_provider = Some(provider);
11433                    });
11434                    notify_server_capabilities_updated(&server, cx);
11435                }
11436                "textDocument/signatureHelp" => {
11437                    if let Some(caps) = reg
11438                        .register_options
11439                        .map(serde_json::from_value)
11440                        .transpose()?
11441                    {
11442                        server.update_capabilities(|capabilities| {
11443                            capabilities.signature_help_provider = Some(caps);
11444                        });
11445                        notify_server_capabilities_updated(&server, cx);
11446                    }
11447                }
11448                "textDocument/didChange" => {
11449                    if let Some(sync_kind) = reg
11450                        .register_options
11451                        .and_then(|opts| opts.get("syncKind").cloned())
11452                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11453                        .transpose()?
11454                    {
11455                        server.update_capabilities(|capabilities| {
11456                            let mut sync_options =
11457                                Self::take_text_document_sync_options(capabilities);
11458                            sync_options.change = Some(sync_kind);
11459                            capabilities.text_document_sync =
11460                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11461                        });
11462                        notify_server_capabilities_updated(&server, cx);
11463                    }
11464                }
11465                "textDocument/didSave" => {
11466                    if let Some(include_text) = reg
11467                        .register_options
11468                        .map(|opts| {
11469                            let transpose = opts
11470                                .get("includeText")
11471                                .cloned()
11472                                .map(serde_json::from_value::<Option<bool>>)
11473                                .transpose();
11474                            match transpose {
11475                                Ok(value) => Ok(value.flatten()),
11476                                Err(e) => Err(e),
11477                            }
11478                        })
11479                        .transpose()?
11480                    {
11481                        server.update_capabilities(|capabilities| {
11482                            let mut sync_options =
11483                                Self::take_text_document_sync_options(capabilities);
11484                            sync_options.save =
11485                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11486                                    include_text,
11487                                }));
11488                            capabilities.text_document_sync =
11489                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11490                        });
11491                        notify_server_capabilities_updated(&server, cx);
11492                    }
11493                }
11494                "textDocument/codeLens" => {
11495                    if let Some(caps) = reg
11496                        .register_options
11497                        .map(serde_json::from_value)
11498                        .transpose()?
11499                    {
11500                        server.update_capabilities(|capabilities| {
11501                            capabilities.code_lens_provider = Some(caps);
11502                        });
11503                        notify_server_capabilities_updated(&server, cx);
11504                    }
11505                }
11506                "textDocument/diagnostic" => {
11507                    if let Some(caps) = reg
11508                        .register_options
11509                        .map(serde_json::from_value)
11510                        .transpose()?
11511                    {
11512                        server.update_capabilities(|capabilities| {
11513                            capabilities.diagnostic_provider = Some(caps);
11514                        });
11515                        notify_server_capabilities_updated(&server, cx);
11516                    }
11517                }
11518                "textDocument/documentColor" => {
11519                    let options = parse_register_capabilities(reg)?;
11520                    let provider = match options {
11521                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
11522                        OneOf::Right(caps) => caps,
11523                    };
11524                    server.update_capabilities(|capabilities| {
11525                        capabilities.color_provider = Some(provider);
11526                    });
11527                    notify_server_capabilities_updated(&server, cx);
11528                }
11529                _ => log::warn!("unhandled capability registration: {reg:?}"),
11530            }
11531        }
11532
11533        Ok(())
11534    }
11535
11536    fn unregister_server_capabilities(
11537        &mut self,
11538        server_id: LanguageServerId,
11539        params: lsp::UnregistrationParams,
11540        cx: &mut Context<Self>,
11541    ) -> anyhow::Result<()> {
11542        let server = self
11543            .language_server_for_id(server_id)
11544            .with_context(|| format!("no server {server_id} found"))?;
11545        for unreg in params.unregisterations.iter() {
11546            match unreg.method.as_str() {
11547                "workspace/didChangeWatchedFiles" => {
11548                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11549                        local_lsp_store
11550                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11551                        true
11552                    } else {
11553                        false
11554                    };
11555                    if notify {
11556                        notify_server_capabilities_updated(&server, cx);
11557                    }
11558                }
11559                "workspace/didChangeConfiguration" => {
11560                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11561                }
11562                "workspace/didChangeWorkspaceFolders" => {
11563                    server.update_capabilities(|capabilities| {
11564                        capabilities
11565                            .workspace
11566                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11567                                workspace_folders: None,
11568                                file_operations: None,
11569                            })
11570                            .workspace_folders = None;
11571                    });
11572                    notify_server_capabilities_updated(&server, cx);
11573                }
11574                "workspace/symbol" => {
11575                    server.update_capabilities(|capabilities| {
11576                        capabilities.workspace_symbol_provider = None
11577                    });
11578                    notify_server_capabilities_updated(&server, cx);
11579                }
11580                "workspace/fileOperations" => {
11581                    server.update_capabilities(|capabilities| {
11582                        capabilities
11583                            .workspace
11584                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11585                                workspace_folders: None,
11586                                file_operations: None,
11587                            })
11588                            .file_operations = None;
11589                    });
11590                    notify_server_capabilities_updated(&server, cx);
11591                }
11592                "workspace/executeCommand" => {
11593                    server.update_capabilities(|capabilities| {
11594                        capabilities.execute_command_provider = None;
11595                    });
11596                    notify_server_capabilities_updated(&server, cx);
11597                }
11598                "textDocument/rangeFormatting" => {
11599                    server.update_capabilities(|capabilities| {
11600                        capabilities.document_range_formatting_provider = None
11601                    });
11602                    notify_server_capabilities_updated(&server, cx);
11603                }
11604                "textDocument/onTypeFormatting" => {
11605                    server.update_capabilities(|capabilities| {
11606                        capabilities.document_on_type_formatting_provider = None;
11607                    });
11608                    notify_server_capabilities_updated(&server, cx);
11609                }
11610                "textDocument/formatting" => {
11611                    server.update_capabilities(|capabilities| {
11612                        capabilities.document_formatting_provider = None;
11613                    });
11614                    notify_server_capabilities_updated(&server, cx);
11615                }
11616                "textDocument/rename" => {
11617                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11618                    notify_server_capabilities_updated(&server, cx);
11619                }
11620                "textDocument/codeAction" => {
11621                    server.update_capabilities(|capabilities| {
11622                        capabilities.code_action_provider = None;
11623                    });
11624                    notify_server_capabilities_updated(&server, cx);
11625                }
11626                "textDocument/definition" => {
11627                    server.update_capabilities(|capabilities| {
11628                        capabilities.definition_provider = None;
11629                    });
11630                    notify_server_capabilities_updated(&server, cx);
11631                }
11632                "textDocument/completion" => {
11633                    server.update_capabilities(|capabilities| {
11634                        capabilities.completion_provider = None;
11635                    });
11636                    notify_server_capabilities_updated(&server, cx);
11637                }
11638                "textDocument/hover" => {
11639                    server.update_capabilities(|capabilities| {
11640                        capabilities.hover_provider = None;
11641                    });
11642                    notify_server_capabilities_updated(&server, cx);
11643                }
11644                "textDocument/signatureHelp" => {
11645                    server.update_capabilities(|capabilities| {
11646                        capabilities.signature_help_provider = None;
11647                    });
11648                    notify_server_capabilities_updated(&server, cx);
11649                }
11650                "textDocument/didChange" => {
11651                    server.update_capabilities(|capabilities| {
11652                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11653                        sync_options.change = None;
11654                        capabilities.text_document_sync =
11655                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11656                    });
11657                    notify_server_capabilities_updated(&server, cx);
11658                }
11659                "textDocument/didSave" => {
11660                    server.update_capabilities(|capabilities| {
11661                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
11662                        sync_options.save = None;
11663                        capabilities.text_document_sync =
11664                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11665                    });
11666                    notify_server_capabilities_updated(&server, cx);
11667                }
11668                "textDocument/codeLens" => {
11669                    server.update_capabilities(|capabilities| {
11670                        capabilities.code_lens_provider = None;
11671                    });
11672                    notify_server_capabilities_updated(&server, cx);
11673                }
11674                "textDocument/diagnostic" => {
11675                    server.update_capabilities(|capabilities| {
11676                        capabilities.diagnostic_provider = None;
11677                    });
11678                    notify_server_capabilities_updated(&server, cx);
11679                }
11680                "textDocument/documentColor" => {
11681                    server.update_capabilities(|capabilities| {
11682                        capabilities.color_provider = None;
11683                    });
11684                    notify_server_capabilities_updated(&server, cx);
11685                }
11686                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
11687            }
11688        }
11689
11690        Ok(())
11691    }
11692
11693    async fn query_lsp_locally<T>(
11694        lsp_store: Entity<Self>,
11695        sender_id: proto::PeerId,
11696        lsp_request_id: LspRequestId,
11697        proto_request: T::ProtoRequest,
11698        position: Option<Anchor>,
11699        mut cx: AsyncApp,
11700    ) -> Result<()>
11701    where
11702        T: LspCommand + Clone,
11703        T::ProtoRequest: proto::LspRequestMessage,
11704        <T::ProtoRequest as proto::RequestMessage>::Response:
11705            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
11706    {
11707        let buffer_id = BufferId::new(proto_request.buffer_id())?;
11708        let version = deserialize_version(proto_request.buffer_version());
11709        let buffer = lsp_store.update(&mut cx, |this, cx| {
11710            this.buffer_store.read(cx).get_existing(buffer_id)
11711        })??;
11712        buffer
11713            .update(&mut cx, |buffer, _| {
11714                buffer.wait_for_version(version.clone())
11715            })?
11716            .await?;
11717        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
11718        let request =
11719            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
11720        lsp_store.update(&mut cx, |lsp_store, cx| {
11721            let request_task =
11722                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
11723            let existing_queries = lsp_store
11724                .running_lsp_requests
11725                .entry(TypeId::of::<T>())
11726                .or_default();
11727            if T::ProtoRequest::stop_previous_requests()
11728                || buffer_version.changed_since(&existing_queries.0)
11729            {
11730                existing_queries.1.clear();
11731            }
11732            existing_queries.1.insert(
11733                lsp_request_id,
11734                cx.spawn(async move |lsp_store, cx| {
11735                    let response = request_task.await;
11736                    lsp_store
11737                        .update(cx, |lsp_store, cx| {
11738                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
11739                            {
11740                                let response = response
11741                                    .into_iter()
11742                                    .map(|(server_id, response)| {
11743                                        (
11744                                            server_id.to_proto(),
11745                                            T::response_to_proto(
11746                                                response,
11747                                                lsp_store,
11748                                                sender_id,
11749                                                &buffer_version,
11750                                                cx,
11751                                            )
11752                                            .into(),
11753                                        )
11754                                    })
11755                                    .collect::<HashMap<_, _>>();
11756                                match client.send_lsp_response::<T::ProtoRequest>(
11757                                    project_id,
11758                                    lsp_request_id,
11759                                    response,
11760                                ) {
11761                                    Ok(()) => {}
11762                                    Err(e) => {
11763                                        log::error!("Failed to send LSP response: {e:#}",)
11764                                    }
11765                                }
11766                            }
11767                        })
11768                        .ok();
11769                }),
11770            );
11771        })?;
11772        Ok(())
11773    }
11774
11775    fn take_text_document_sync_options(
11776        capabilities: &mut lsp::ServerCapabilities,
11777    ) -> lsp::TextDocumentSyncOptions {
11778        match capabilities.text_document_sync.take() {
11779            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
11780            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
11781                let mut sync_options = lsp::TextDocumentSyncOptions::default();
11782                sync_options.change = Some(sync_kind);
11783                sync_options
11784            }
11785            None => lsp::TextDocumentSyncOptions::default(),
11786        }
11787    }
11788
11789    #[cfg(any(test, feature = "test-support"))]
11790    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
11791        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
11792        Some(data.update.take()?.1)
11793    }
11794
11795    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
11796        self.downstream_client.clone()
11797    }
11798
11799    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
11800        self.worktree_store.clone()
11801    }
11802}
11803
11804// Registration with registerOptions as null, should fallback to true.
11805// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
11806fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
11807    reg: lsp::Registration,
11808) -> Result<OneOf<bool, T>> {
11809    Ok(match reg.register_options {
11810        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
11811        None => OneOf::Left(true),
11812    })
11813}
11814
11815fn subscribe_to_binary_statuses(
11816    languages: &Arc<LanguageRegistry>,
11817    cx: &mut Context<'_, LspStore>,
11818) -> Task<()> {
11819    let mut server_statuses = languages.language_server_binary_statuses();
11820    cx.spawn(async move |lsp_store, cx| {
11821        while let Some((server_name, binary_status)) = server_statuses.next().await {
11822            if lsp_store
11823                .update(cx, |_, cx| {
11824                    let mut message = None;
11825                    let binary_status = match binary_status {
11826                        BinaryStatus::None => proto::ServerBinaryStatus::None,
11827                        BinaryStatus::CheckingForUpdate => {
11828                            proto::ServerBinaryStatus::CheckingForUpdate
11829                        }
11830                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
11831                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
11832                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
11833                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
11834                        BinaryStatus::Failed { error } => {
11835                            message = Some(error);
11836                            proto::ServerBinaryStatus::Failed
11837                        }
11838                    };
11839                    cx.emit(LspStoreEvent::LanguageServerUpdate {
11840                        // Binary updates are about the binary that might not have any language server id at that point.
11841                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
11842                        language_server_id: LanguageServerId(0),
11843                        name: Some(server_name),
11844                        message: proto::update_language_server::Variant::StatusUpdate(
11845                            proto::StatusUpdate {
11846                                message,
11847                                status: Some(proto::status_update::Status::Binary(
11848                                    binary_status as i32,
11849                                )),
11850                            },
11851                        ),
11852                    });
11853                })
11854                .is_err()
11855            {
11856                break;
11857            }
11858        }
11859    })
11860}
11861
11862fn lsp_workspace_diagnostics_refresh(
11863    server: Arc<LanguageServer>,
11864    cx: &mut Context<'_, LspStore>,
11865) -> Option<WorkspaceRefreshTask> {
11866    let identifier = match server.capabilities().diagnostic_provider? {
11867        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
11868            if !diagnostic_options.workspace_diagnostics {
11869                return None;
11870            }
11871            diagnostic_options.identifier
11872        }
11873        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
11874            let diagnostic_options = registration_options.diagnostic_options;
11875            if !diagnostic_options.workspace_diagnostics {
11876                return None;
11877            }
11878            diagnostic_options.identifier
11879        }
11880    };
11881
11882    let (progress_tx, mut progress_rx) = mpsc::channel(1);
11883    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
11884    refresh_tx.try_send(()).ok();
11885
11886    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
11887        let mut attempts = 0;
11888        let max_attempts = 50;
11889        let mut requests = 0;
11890
11891        loop {
11892            let Some(()) = refresh_rx.recv().await else {
11893                return;
11894            };
11895
11896            'request: loop {
11897                requests += 1;
11898                if attempts > max_attempts {
11899                    log::error!(
11900                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
11901                    );
11902                    return;
11903                }
11904                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
11905                cx.background_executor()
11906                    .timer(Duration::from_millis(backoff_millis))
11907                    .await;
11908                attempts += 1;
11909
11910                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
11911                    lsp_store
11912                        .all_result_ids(server.server_id())
11913                        .into_iter()
11914                        .filter_map(|(abs_path, result_id)| {
11915                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
11916                            Some(lsp::PreviousResultId {
11917                                uri,
11918                                value: result_id,
11919                            })
11920                        })
11921                        .collect()
11922                }) else {
11923                    return;
11924                };
11925
11926                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
11927
11928                progress_rx.try_recv().ok();
11929                let timer =
11930                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
11931                let progress = pin!(progress_rx.recv().fuse());
11932                let response_result = server
11933                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
11934                        lsp::WorkspaceDiagnosticParams {
11935                            previous_result_ids,
11936                            identifier: identifier.clone(),
11937                            work_done_progress_params: Default::default(),
11938                            partial_result_params: lsp::PartialResultParams {
11939                                partial_result_token: Some(lsp::ProgressToken::String(token)),
11940                            },
11941                        },
11942                        select(timer, progress).then(|either| match either {
11943                            Either::Left((message, ..)) => ready(message).left_future(),
11944                            Either::Right(..) => pending::<String>().right_future(),
11945                        }),
11946                    )
11947                    .await;
11948
11949                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
11950                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
11951                match response_result {
11952                    ConnectionResult::Timeout => {
11953                        log::error!("Timeout during workspace diagnostics pull");
11954                        continue 'request;
11955                    }
11956                    ConnectionResult::ConnectionReset => {
11957                        log::error!("Server closed a workspace diagnostics pull request");
11958                        continue 'request;
11959                    }
11960                    ConnectionResult::Result(Err(e)) => {
11961                        log::error!("Error during workspace diagnostics pull: {e:#}");
11962                        break 'request;
11963                    }
11964                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
11965                        attempts = 0;
11966                        if lsp_store
11967                            .update(cx, |lsp_store, cx| {
11968                                lsp_store.apply_workspace_diagnostic_report(
11969                                    server.server_id(),
11970                                    pulled_diagnostics,
11971                                    cx,
11972                                )
11973                            })
11974                            .is_err()
11975                        {
11976                            return;
11977                        }
11978                        break 'request;
11979                    }
11980                }
11981            }
11982        }
11983    });
11984
11985    Some(WorkspaceRefreshTask {
11986        refresh_tx,
11987        progress_tx,
11988        task: workspace_query_language_server,
11989    })
11990}
11991
11992fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
11993    let CompletionSource::BufferWord {
11994        word_range,
11995        resolved,
11996    } = &mut completion.source
11997    else {
11998        return;
11999    };
12000    if *resolved {
12001        return;
12002    }
12003
12004    if completion.new_text
12005        != snapshot
12006            .text_for_range(word_range.clone())
12007            .collect::<String>()
12008    {
12009        return;
12010    }
12011
12012    let mut offset = 0;
12013    for chunk in snapshot.chunks(word_range.clone(), true) {
12014        let end_offset = offset + chunk.text.len();
12015        if let Some(highlight_id) = chunk.syntax_highlight_id {
12016            completion
12017                .label
12018                .runs
12019                .push((offset..end_offset, highlight_id));
12020        }
12021        offset = end_offset;
12022    }
12023    *resolved = true;
12024}
12025
12026impl EventEmitter<LspStoreEvent> for LspStore {}
12027
12028fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12029    hover
12030        .contents
12031        .retain(|hover_block| !hover_block.text.trim().is_empty());
12032    if hover.contents.is_empty() {
12033        None
12034    } else {
12035        Some(hover)
12036    }
12037}
12038
12039async fn populate_labels_for_completions(
12040    new_completions: Vec<CoreCompletion>,
12041    language: Option<Arc<Language>>,
12042    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12043) -> Vec<Completion> {
12044    let lsp_completions = new_completions
12045        .iter()
12046        .filter_map(|new_completion| {
12047            new_completion
12048                .source
12049                .lsp_completion(true)
12050                .map(|lsp_completion| lsp_completion.into_owned())
12051        })
12052        .collect::<Vec<_>>();
12053
12054    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12055        lsp_adapter
12056            .labels_for_completions(&lsp_completions, language)
12057            .await
12058            .log_err()
12059            .unwrap_or_default()
12060    } else {
12061        Vec::new()
12062    }
12063    .into_iter()
12064    .fuse();
12065
12066    let mut completions = Vec::new();
12067    for completion in new_completions {
12068        match completion.source.lsp_completion(true) {
12069            Some(lsp_completion) => {
12070                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12071
12072                let mut label = labels.next().flatten().unwrap_or_else(|| {
12073                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12074                });
12075                ensure_uniform_list_compatible_label(&mut label);
12076                completions.push(Completion {
12077                    label,
12078                    documentation,
12079                    replace_range: completion.replace_range,
12080                    new_text: completion.new_text,
12081                    insert_text_mode: lsp_completion.insert_text_mode,
12082                    source: completion.source,
12083                    icon_path: None,
12084                    confirm: None,
12085                });
12086            }
12087            None => {
12088                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12089                ensure_uniform_list_compatible_label(&mut label);
12090                completions.push(Completion {
12091                    label,
12092                    documentation: None,
12093                    replace_range: completion.replace_range,
12094                    new_text: completion.new_text,
12095                    source: completion.source,
12096                    insert_text_mode: None,
12097                    icon_path: None,
12098                    confirm: None,
12099                });
12100            }
12101        }
12102    }
12103    completions
12104}
12105
12106#[derive(Debug)]
12107pub enum LanguageServerToQuery {
12108    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12109    FirstCapable,
12110    /// Query a specific language server.
12111    Other(LanguageServerId),
12112}
12113
12114#[derive(Default)]
12115struct RenamePathsWatchedForServer {
12116    did_rename: Vec<RenameActionPredicate>,
12117    will_rename: Vec<RenameActionPredicate>,
12118}
12119
12120impl RenamePathsWatchedForServer {
12121    fn with_did_rename_patterns(
12122        mut self,
12123        did_rename: Option<&FileOperationRegistrationOptions>,
12124    ) -> Self {
12125        if let Some(did_rename) = did_rename {
12126            self.did_rename = did_rename
12127                .filters
12128                .iter()
12129                .filter_map(|filter| filter.try_into().log_err())
12130                .collect();
12131        }
12132        self
12133    }
12134    fn with_will_rename_patterns(
12135        mut self,
12136        will_rename: Option<&FileOperationRegistrationOptions>,
12137    ) -> Self {
12138        if let Some(will_rename) = will_rename {
12139            self.will_rename = will_rename
12140                .filters
12141                .iter()
12142                .filter_map(|filter| filter.try_into().log_err())
12143                .collect();
12144        }
12145        self
12146    }
12147
12148    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12149        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12150    }
12151    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12152        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12153    }
12154}
12155
12156impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12157    type Error = globset::Error;
12158    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12159        Ok(Self {
12160            kind: ops.pattern.matches.clone(),
12161            glob: GlobBuilder::new(&ops.pattern.glob)
12162                .case_insensitive(
12163                    ops.pattern
12164                        .options
12165                        .as_ref()
12166                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12167                )
12168                .build()?
12169                .compile_matcher(),
12170        })
12171    }
12172}
12173struct RenameActionPredicate {
12174    glob: GlobMatcher,
12175    kind: Option<FileOperationPatternKind>,
12176}
12177
12178impl RenameActionPredicate {
12179    // Returns true if language server should be notified
12180    fn eval(&self, path: &str, is_dir: bool) -> bool {
12181        self.kind.as_ref().is_none_or(|kind| {
12182            let expected_kind = if is_dir {
12183                FileOperationPatternKind::Folder
12184            } else {
12185                FileOperationPatternKind::File
12186            };
12187            kind == &expected_kind
12188        }) && self.glob.is_match(path)
12189    }
12190}
12191
12192#[derive(Default)]
12193struct LanguageServerWatchedPaths {
12194    worktree_paths: HashMap<WorktreeId, GlobSet>,
12195    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12196}
12197
12198#[derive(Default)]
12199struct LanguageServerWatchedPathsBuilder {
12200    worktree_paths: HashMap<WorktreeId, GlobSet>,
12201    abs_paths: HashMap<Arc<Path>, GlobSet>,
12202}
12203
12204impl LanguageServerWatchedPathsBuilder {
12205    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12206        self.worktree_paths.insert(worktree_id, glob_set);
12207    }
12208    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12209        self.abs_paths.insert(path, glob_set);
12210    }
12211    fn build(
12212        self,
12213        fs: Arc<dyn Fs>,
12214        language_server_id: LanguageServerId,
12215        cx: &mut Context<LspStore>,
12216    ) -> LanguageServerWatchedPaths {
12217        let project = cx.weak_entity();
12218
12219        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12220        let abs_paths = self
12221            .abs_paths
12222            .into_iter()
12223            .map(|(abs_path, globset)| {
12224                let task = cx.spawn({
12225                    let abs_path = abs_path.clone();
12226                    let fs = fs.clone();
12227
12228                    let lsp_store = project.clone();
12229                    async move |_, cx| {
12230                        maybe!(async move {
12231                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12232                            while let Some(update) = push_updates.0.next().await {
12233                                let action = lsp_store
12234                                    .update(cx, |this, _| {
12235                                        let Some(local) = this.as_local() else {
12236                                            return ControlFlow::Break(());
12237                                        };
12238                                        let Some(watcher) = local
12239                                            .language_server_watched_paths
12240                                            .get(&language_server_id)
12241                                        else {
12242                                            return ControlFlow::Break(());
12243                                        };
12244                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12245                                            "Watched abs path is not registered with a watcher",
12246                                        );
12247                                        let matching_entries = update
12248                                            .into_iter()
12249                                            .filter(|event| globs.is_match(&event.path))
12250                                            .collect::<Vec<_>>();
12251                                        this.lsp_notify_abs_paths_changed(
12252                                            language_server_id,
12253                                            matching_entries,
12254                                        );
12255                                        ControlFlow::Continue(())
12256                                    })
12257                                    .ok()?;
12258
12259                                if action.is_break() {
12260                                    break;
12261                                }
12262                            }
12263                            Some(())
12264                        })
12265                        .await;
12266                    }
12267                });
12268                (abs_path, (globset, task))
12269            })
12270            .collect();
12271        LanguageServerWatchedPaths {
12272            worktree_paths: self.worktree_paths,
12273            abs_paths,
12274        }
12275    }
12276}
12277
12278struct LspBufferSnapshot {
12279    version: i32,
12280    snapshot: TextBufferSnapshot,
12281}
12282
12283/// A prompt requested by LSP server.
12284#[derive(Clone, Debug)]
12285pub struct LanguageServerPromptRequest {
12286    pub level: PromptLevel,
12287    pub message: String,
12288    pub actions: Vec<MessageActionItem>,
12289    pub lsp_name: String,
12290    pub(crate) response_channel: Sender<MessageActionItem>,
12291}
12292
12293impl LanguageServerPromptRequest {
12294    pub async fn respond(self, index: usize) -> Option<()> {
12295        if let Some(response) = self.actions.into_iter().nth(index) {
12296            self.response_channel.send(response).await.ok()
12297        } else {
12298            None
12299        }
12300    }
12301}
12302impl PartialEq for LanguageServerPromptRequest {
12303    fn eq(&self, other: &Self) -> bool {
12304        self.message == other.message && self.actions == other.actions
12305    }
12306}
12307
12308#[derive(Clone, Debug, PartialEq)]
12309pub enum LanguageServerLogType {
12310    Log(MessageType),
12311    Trace { verbose_info: Option<String> },
12312    Rpc { received: bool },
12313}
12314
12315impl LanguageServerLogType {
12316    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12317        match self {
12318            Self::Log(log_type) => {
12319                use proto::log_message::LogLevel;
12320                let level = match *log_type {
12321                    MessageType::ERROR => LogLevel::Error,
12322                    MessageType::WARNING => LogLevel::Warning,
12323                    MessageType::INFO => LogLevel::Info,
12324                    MessageType::LOG => LogLevel::Log,
12325                    other => {
12326                        log::warn!("Unknown lsp log message type: {other:?}");
12327                        LogLevel::Log
12328                    }
12329                };
12330                proto::language_server_log::LogType::Log(proto::LogMessage {
12331                    level: level as i32,
12332                })
12333            }
12334            Self::Trace { verbose_info } => {
12335                proto::language_server_log::LogType::Trace(proto::TraceMessage {
12336                    verbose_info: verbose_info.to_owned(),
12337                })
12338            }
12339            Self::Rpc { received } => {
12340                let kind = if *received {
12341                    proto::rpc_message::Kind::Received
12342                } else {
12343                    proto::rpc_message::Kind::Sent
12344                };
12345                let kind = kind as i32;
12346                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
12347            }
12348        }
12349    }
12350
12351    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12352        use proto::log_message::LogLevel;
12353        use proto::rpc_message;
12354        match log_type {
12355            proto::language_server_log::LogType::Log(message_type) => Self::Log(
12356                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
12357                    LogLevel::Error => MessageType::ERROR,
12358                    LogLevel::Warning => MessageType::WARNING,
12359                    LogLevel::Info => MessageType::INFO,
12360                    LogLevel::Log => MessageType::LOG,
12361                },
12362            ),
12363            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
12364                verbose_info: trace_message.verbose_info,
12365            },
12366            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
12367                received: match rpc_message::Kind::from_i32(message.kind)
12368                    .unwrap_or(rpc_message::Kind::Received)
12369                {
12370                    rpc_message::Kind::Received => true,
12371                    rpc_message::Kind::Sent => false,
12372                },
12373            },
12374        }
12375    }
12376}
12377
12378pub struct WorkspaceRefreshTask {
12379    refresh_tx: mpsc::Sender<()>,
12380    progress_tx: mpsc::Sender<()>,
12381    #[allow(dead_code)]
12382    task: Task<()>,
12383}
12384
12385pub enum LanguageServerState {
12386    Starting {
12387        startup: Task<Option<Arc<LanguageServer>>>,
12388        /// List of language servers that will be added to the workspace once it's initialization completes.
12389        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
12390    },
12391
12392    Running {
12393        adapter: Arc<CachedLspAdapter>,
12394        server: Arc<LanguageServer>,
12395        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12396        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12397    },
12398}
12399
12400impl LanguageServerState {
12401    fn add_workspace_folder(&self, uri: Uri) {
12402        match self {
12403            LanguageServerState::Starting {
12404                pending_workspace_folders,
12405                ..
12406            } => {
12407                pending_workspace_folders.lock().insert(uri);
12408            }
12409            LanguageServerState::Running { server, .. } => {
12410                server.add_workspace_folder(uri);
12411            }
12412        }
12413    }
12414    fn _remove_workspace_folder(&self, uri: Uri) {
12415        match self {
12416            LanguageServerState::Starting {
12417                pending_workspace_folders,
12418                ..
12419            } => {
12420                pending_workspace_folders.lock().remove(&uri);
12421            }
12422            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12423        }
12424    }
12425}
12426
12427impl std::fmt::Debug for LanguageServerState {
12428    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12429        match self {
12430            LanguageServerState::Starting { .. } => {
12431                f.debug_struct("LanguageServerState::Starting").finish()
12432            }
12433            LanguageServerState::Running { .. } => {
12434                f.debug_struct("LanguageServerState::Running").finish()
12435            }
12436        }
12437    }
12438}
12439
12440#[derive(Clone, Debug, Serialize)]
12441pub struct LanguageServerProgress {
12442    pub is_disk_based_diagnostics_progress: bool,
12443    pub is_cancellable: bool,
12444    pub title: Option<String>,
12445    pub message: Option<String>,
12446    pub percentage: Option<usize>,
12447    #[serde(skip_serializing)]
12448    pub last_update_at: Instant,
12449}
12450
12451#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12452pub struct DiagnosticSummary {
12453    pub error_count: usize,
12454    pub warning_count: usize,
12455}
12456
12457impl DiagnosticSummary {
12458    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12459        let mut this = Self {
12460            error_count: 0,
12461            warning_count: 0,
12462        };
12463
12464        for entry in diagnostics {
12465            if entry.diagnostic.is_primary {
12466                match entry.diagnostic.severity {
12467                    DiagnosticSeverity::ERROR => this.error_count += 1,
12468                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12469                    _ => {}
12470                }
12471            }
12472        }
12473
12474        this
12475    }
12476
12477    pub fn is_empty(&self) -> bool {
12478        self.error_count == 0 && self.warning_count == 0
12479    }
12480
12481    pub fn to_proto(
12482        self,
12483        language_server_id: LanguageServerId,
12484        path: &Path,
12485    ) -> proto::DiagnosticSummary {
12486        proto::DiagnosticSummary {
12487            path: path.to_proto(),
12488            language_server_id: language_server_id.0 as u64,
12489            error_count: self.error_count as u32,
12490            warning_count: self.warning_count as u32,
12491        }
12492    }
12493}
12494
12495#[derive(Clone, Debug)]
12496pub enum CompletionDocumentation {
12497    /// There is no documentation for this completion.
12498    Undocumented,
12499    /// A single line of documentation.
12500    SingleLine(SharedString),
12501    /// Multiple lines of plain text documentation.
12502    MultiLinePlainText(SharedString),
12503    /// Markdown documentation.
12504    MultiLineMarkdown(SharedString),
12505    /// Both single line and multiple lines of plain text documentation.
12506    SingleLineAndMultiLinePlainText {
12507        single_line: SharedString,
12508        plain_text: Option<SharedString>,
12509    },
12510}
12511
12512impl CompletionDocumentation {
12513    #[cfg(any(test, feature = "test-support"))]
12514    pub fn text(&self) -> SharedString {
12515        match self {
12516            CompletionDocumentation::Undocumented => "".into(),
12517            CompletionDocumentation::SingleLine(s) => s.clone(),
12518            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
12519            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
12520            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
12521                single_line.clone()
12522            }
12523        }
12524    }
12525}
12526
12527impl From<lsp::Documentation> for CompletionDocumentation {
12528    fn from(docs: lsp::Documentation) -> Self {
12529        match docs {
12530            lsp::Documentation::String(text) => {
12531                if text.lines().count() <= 1 {
12532                    CompletionDocumentation::SingleLine(text.into())
12533                } else {
12534                    CompletionDocumentation::MultiLinePlainText(text.into())
12535                }
12536            }
12537
12538            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12539                lsp::MarkupKind::PlainText => {
12540                    if value.lines().count() <= 1 {
12541                        CompletionDocumentation::SingleLine(value.into())
12542                    } else {
12543                        CompletionDocumentation::MultiLinePlainText(value.into())
12544                    }
12545                }
12546
12547                lsp::MarkupKind::Markdown => {
12548                    CompletionDocumentation::MultiLineMarkdown(value.into())
12549                }
12550            },
12551        }
12552    }
12553}
12554
12555fn glob_literal_prefix(glob: &Path) -> PathBuf {
12556    glob.components()
12557        .take_while(|component| match component {
12558            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12559            _ => true,
12560        })
12561        .collect()
12562}
12563
12564pub struct SshLspAdapter {
12565    name: LanguageServerName,
12566    binary: LanguageServerBinary,
12567    initialization_options: Option<String>,
12568    code_action_kinds: Option<Vec<CodeActionKind>>,
12569}
12570
12571impl SshLspAdapter {
12572    pub fn new(
12573        name: LanguageServerName,
12574        binary: LanguageServerBinary,
12575        initialization_options: Option<String>,
12576        code_action_kinds: Option<String>,
12577    ) -> Self {
12578        Self {
12579            name,
12580            binary,
12581            initialization_options,
12582            code_action_kinds: code_action_kinds
12583                .as_ref()
12584                .and_then(|c| serde_json::from_str(c).ok()),
12585        }
12586    }
12587}
12588
12589impl LspInstaller for SshLspAdapter {
12590    type BinaryVersion = ();
12591    async fn check_if_user_installed(
12592        &self,
12593        _: &dyn LspAdapterDelegate,
12594        _: Option<Toolchain>,
12595        _: &AsyncApp,
12596    ) -> Option<LanguageServerBinary> {
12597        Some(self.binary.clone())
12598    }
12599
12600    async fn cached_server_binary(
12601        &self,
12602        _: PathBuf,
12603        _: &dyn LspAdapterDelegate,
12604    ) -> Option<LanguageServerBinary> {
12605        None
12606    }
12607
12608    async fn fetch_latest_server_version(
12609        &self,
12610        _: &dyn LspAdapterDelegate,
12611        _: bool,
12612        _: &mut AsyncApp,
12613    ) -> Result<()> {
12614        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12615    }
12616
12617    async fn fetch_server_binary(
12618        &self,
12619        _: (),
12620        _: PathBuf,
12621        _: &dyn LspAdapterDelegate,
12622    ) -> Result<LanguageServerBinary> {
12623        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12624    }
12625}
12626
12627#[async_trait(?Send)]
12628impl LspAdapter for SshLspAdapter {
12629    fn name(&self) -> LanguageServerName {
12630        self.name.clone()
12631    }
12632
12633    async fn initialization_options(
12634        self: Arc<Self>,
12635        _: &Arc<dyn LspAdapterDelegate>,
12636    ) -> Result<Option<serde_json::Value>> {
12637        let Some(options) = &self.initialization_options else {
12638            return Ok(None);
12639        };
12640        let result = serde_json::from_str(options)?;
12641        Ok(result)
12642    }
12643
12644    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12645        self.code_action_kinds.clone()
12646    }
12647}
12648
12649pub fn language_server_settings<'a>(
12650    delegate: &'a dyn LspAdapterDelegate,
12651    language: &LanguageServerName,
12652    cx: &'a App,
12653) -> Option<&'a LspSettings> {
12654    language_server_settings_for(
12655        SettingsLocation {
12656            worktree_id: delegate.worktree_id(),
12657            path: delegate.worktree_root_path(),
12658        },
12659        language,
12660        cx,
12661    )
12662}
12663
12664pub(crate) fn language_server_settings_for<'a>(
12665    location: SettingsLocation<'a>,
12666    language: &LanguageServerName,
12667    cx: &'a App,
12668) -> Option<&'a LspSettings> {
12669    ProjectSettings::get(Some(location), cx).lsp.get(language)
12670}
12671
12672pub struct LocalLspAdapterDelegate {
12673    lsp_store: WeakEntity<LspStore>,
12674    worktree: worktree::Snapshot,
12675    fs: Arc<dyn Fs>,
12676    http_client: Arc<dyn HttpClient>,
12677    language_registry: Arc<LanguageRegistry>,
12678    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12679}
12680
12681impl LocalLspAdapterDelegate {
12682    pub fn new(
12683        language_registry: Arc<LanguageRegistry>,
12684        environment: &Entity<ProjectEnvironment>,
12685        lsp_store: WeakEntity<LspStore>,
12686        worktree: &Entity<Worktree>,
12687        http_client: Arc<dyn HttpClient>,
12688        fs: Arc<dyn Fs>,
12689        cx: &mut App,
12690    ) -> Arc<Self> {
12691        let load_shell_env_task = environment.update(cx, |env, cx| {
12692            env.get_worktree_environment(worktree.clone(), cx)
12693        });
12694
12695        Arc::new(Self {
12696            lsp_store,
12697            worktree: worktree.read(cx).snapshot(),
12698            fs,
12699            http_client,
12700            language_registry,
12701            load_shell_env_task,
12702        })
12703    }
12704
12705    fn from_local_lsp(
12706        local: &LocalLspStore,
12707        worktree: &Entity<Worktree>,
12708        cx: &mut App,
12709    ) -> Arc<Self> {
12710        Self::new(
12711            local.languages.clone(),
12712            &local.environment,
12713            local.weak.clone(),
12714            worktree,
12715            local.http_client.clone(),
12716            local.fs.clone(),
12717            cx,
12718        )
12719    }
12720}
12721
12722#[async_trait]
12723impl LspAdapterDelegate for LocalLspAdapterDelegate {
12724    fn show_notification(&self, message: &str, cx: &mut App) {
12725        self.lsp_store
12726            .update(cx, |_, cx| {
12727                cx.emit(LspStoreEvent::Notification(message.to_owned()))
12728            })
12729            .ok();
12730    }
12731
12732    fn http_client(&self) -> Arc<dyn HttpClient> {
12733        self.http_client.clone()
12734    }
12735
12736    fn worktree_id(&self) -> WorktreeId {
12737        self.worktree.id()
12738    }
12739
12740    fn worktree_root_path(&self) -> &Path {
12741        self.worktree.abs_path().as_ref()
12742    }
12743
12744    async fn shell_env(&self) -> HashMap<String, String> {
12745        let task = self.load_shell_env_task.clone();
12746        task.await.unwrap_or_default()
12747    }
12748
12749    async fn npm_package_installed_version(
12750        &self,
12751        package_name: &str,
12752    ) -> Result<Option<(PathBuf, String)>> {
12753        let local_package_directory = self.worktree_root_path();
12754        let node_modules_directory = local_package_directory.join("node_modules");
12755
12756        if let Some(version) =
12757            read_package_installed_version(node_modules_directory.clone(), package_name).await?
12758        {
12759            return Ok(Some((node_modules_directory, version)));
12760        }
12761        let Some(npm) = self.which("npm".as_ref()).await else {
12762            log::warn!(
12763                "Failed to find npm executable for {:?}",
12764                local_package_directory
12765            );
12766            return Ok(None);
12767        };
12768
12769        let env = self.shell_env().await;
12770        let output = util::command::new_smol_command(&npm)
12771            .args(["root", "-g"])
12772            .envs(env)
12773            .current_dir(local_package_directory)
12774            .output()
12775            .await?;
12776        let global_node_modules =
12777            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
12778
12779        if let Some(version) =
12780            read_package_installed_version(global_node_modules.clone(), package_name).await?
12781        {
12782            return Ok(Some((global_node_modules, version)));
12783        }
12784        return Ok(None);
12785    }
12786
12787    #[cfg(not(target_os = "windows"))]
12788    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12789        let worktree_abs_path = self.worktree.abs_path();
12790        let shell_path = self.shell_env().await.get("PATH").cloned();
12791        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
12792    }
12793
12794    #[cfg(target_os = "windows")]
12795    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
12796        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
12797        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
12798        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
12799        which::which(command).ok()
12800    }
12801
12802    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
12803        let working_dir = self.worktree_root_path();
12804        let output = util::command::new_smol_command(&command.path)
12805            .args(command.arguments)
12806            .envs(command.env.clone().unwrap_or_default())
12807            .current_dir(working_dir)
12808            .output()
12809            .await?;
12810
12811        anyhow::ensure!(
12812            output.status.success(),
12813            "{}, stdout: {:?}, stderr: {:?}",
12814            output.status,
12815            String::from_utf8_lossy(&output.stdout),
12816            String::from_utf8_lossy(&output.stderr)
12817        );
12818        Ok(())
12819    }
12820
12821    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
12822        self.language_registry
12823            .update_lsp_binary_status(server_name, status);
12824    }
12825
12826    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
12827        self.language_registry
12828            .all_lsp_adapters()
12829            .into_iter()
12830            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
12831            .collect()
12832    }
12833
12834    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
12835        let dir = self.language_registry.language_server_download_dir(name)?;
12836
12837        if !dir.exists() {
12838            smol::fs::create_dir_all(&dir)
12839                .await
12840                .context("failed to create container directory")
12841                .log_err()?;
12842        }
12843
12844        Some(dir)
12845    }
12846
12847    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
12848        let entry = self
12849            .worktree
12850            .entry_for_path(&path)
12851            .with_context(|| format!("no worktree entry for path {path:?}"))?;
12852        let abs_path = self
12853            .worktree
12854            .absolutize(&entry.path)
12855            .with_context(|| format!("cannot absolutize path {path:?}"))?;
12856
12857        self.fs.load(&abs_path).await
12858    }
12859}
12860
12861async fn populate_labels_for_symbols(
12862    symbols: Vec<CoreSymbol>,
12863    language_registry: &Arc<LanguageRegistry>,
12864    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12865    output: &mut Vec<Symbol>,
12866) {
12867    #[allow(clippy::mutable_key_type)]
12868    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
12869
12870    let mut unknown_paths = BTreeSet::new();
12871    for symbol in symbols {
12872        let language = language_registry
12873            .language_for_file_path(&symbol.path.path)
12874            .await
12875            .ok()
12876            .or_else(|| {
12877                unknown_paths.insert(symbol.path.path.clone());
12878                None
12879            });
12880        symbols_by_language
12881            .entry(language)
12882            .or_default()
12883            .push(symbol);
12884    }
12885
12886    for unknown_path in unknown_paths {
12887        log::info!(
12888            "no language found for symbol path {}",
12889            unknown_path.display()
12890        );
12891    }
12892
12893    let mut label_params = Vec::new();
12894    for (language, mut symbols) in symbols_by_language {
12895        label_params.clear();
12896        label_params.extend(
12897            symbols
12898                .iter_mut()
12899                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
12900        );
12901
12902        let mut labels = Vec::new();
12903        if let Some(language) = language {
12904            let lsp_adapter = lsp_adapter.clone().or_else(|| {
12905                language_registry
12906                    .lsp_adapters(&language.name())
12907                    .first()
12908                    .cloned()
12909            });
12910            if let Some(lsp_adapter) = lsp_adapter {
12911                labels = lsp_adapter
12912                    .labels_for_symbols(&label_params, &language)
12913                    .await
12914                    .log_err()
12915                    .unwrap_or_default();
12916            }
12917        }
12918
12919        for ((symbol, (name, _)), label) in symbols
12920            .into_iter()
12921            .zip(label_params.drain(..))
12922            .zip(labels.into_iter().chain(iter::repeat(None)))
12923        {
12924            output.push(Symbol {
12925                language_server_name: symbol.language_server_name,
12926                source_worktree_id: symbol.source_worktree_id,
12927                source_language_server_id: symbol.source_language_server_id,
12928                path: symbol.path,
12929                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
12930                name,
12931                kind: symbol.kind,
12932                range: symbol.range,
12933                signature: symbol.signature,
12934            });
12935        }
12936    }
12937}
12938
12939fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
12940    match server.capabilities().text_document_sync.as_ref()? {
12941        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
12942            // Server wants didSave but didn't specify includeText.
12943            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
12944            // Server doesn't want didSave at all.
12945            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
12946            // Server provided SaveOptions.
12947            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
12948                Some(save_options.include_text.unwrap_or(false))
12949            }
12950        },
12951        // We do not have any save info. Kind affects didChange only.
12952        lsp::TextDocumentSyncCapability::Kind(_) => None,
12953    }
12954}
12955
12956/// Completion items are displayed in a `UniformList`.
12957/// Usually, those items are single-line strings, but in LSP responses,
12958/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
12959/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
12960/// All that may lead to a newline being inserted into resulting `CodeLabel.text`, which will force `UniformList` to bloat each entry to occupy more space,
12961/// breaking the completions menu presentation.
12962///
12963/// Sanitize the text to ensure there are no newlines, or, if there are some, remove them and also remove long space sequences if there were newlines.
12964fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
12965    let mut new_text = String::with_capacity(label.text.len());
12966    let mut offset_map = vec![0; label.text.len() + 1];
12967    let mut last_char_was_space = false;
12968    let mut new_idx = 0;
12969    let chars = label.text.char_indices().fuse();
12970    let mut newlines_removed = false;
12971
12972    for (idx, c) in chars {
12973        offset_map[idx] = new_idx;
12974
12975        match c {
12976            '\n' if last_char_was_space => {
12977                newlines_removed = true;
12978            }
12979            '\t' | ' ' if last_char_was_space => {}
12980            '\n' if !last_char_was_space => {
12981                new_text.push(' ');
12982                new_idx += 1;
12983                last_char_was_space = true;
12984                newlines_removed = true;
12985            }
12986            ' ' | '\t' => {
12987                new_text.push(' ');
12988                new_idx += 1;
12989                last_char_was_space = true;
12990            }
12991            _ => {
12992                new_text.push(c);
12993                new_idx += c.len_utf8();
12994                last_char_was_space = false;
12995            }
12996        }
12997    }
12998    offset_map[label.text.len()] = new_idx;
12999
13000    // Only modify the label if newlines were removed.
13001    if !newlines_removed {
13002        return;
13003    }
13004
13005    let last_index = new_idx;
13006    let mut run_ranges_errors = Vec::new();
13007    label.runs.retain_mut(|(range, _)| {
13008        match offset_map.get(range.start) {
13009            Some(&start) => range.start = start,
13010            None => {
13011                run_ranges_errors.push(range.clone());
13012                return false;
13013            }
13014        }
13015
13016        match offset_map.get(range.end) {
13017            Some(&end) => range.end = end,
13018            None => {
13019                run_ranges_errors.push(range.clone());
13020                range.end = last_index;
13021            }
13022        }
13023        true
13024    });
13025    if !run_ranges_errors.is_empty() {
13026        log::error!(
13027            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13028            label.text
13029        );
13030    }
13031
13032    let mut wrong_filter_range = None;
13033    if label.filter_range == (0..label.text.len()) {
13034        label.filter_range = 0..new_text.len();
13035    } else {
13036        let mut original_filter_range = Some(label.filter_range.clone());
13037        match offset_map.get(label.filter_range.start) {
13038            Some(&start) => label.filter_range.start = start,
13039            None => {
13040                wrong_filter_range = original_filter_range.take();
13041                label.filter_range.start = last_index;
13042            }
13043        }
13044
13045        match offset_map.get(label.filter_range.end) {
13046            Some(&end) => label.filter_range.end = end,
13047            None => {
13048                wrong_filter_range = original_filter_range.take();
13049                label.filter_range.end = last_index;
13050            }
13051        }
13052    }
13053    if let Some(wrong_filter_range) = wrong_filter_range {
13054        log::error!(
13055            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13056            label.text
13057        );
13058    }
13059
13060    label.text = new_text;
13061}
13062
13063#[cfg(test)]
13064mod tests {
13065    use language::HighlightId;
13066
13067    use super::*;
13068
13069    #[test]
13070    fn test_glob_literal_prefix() {
13071        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13072        assert_eq!(
13073            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13074            Path::new("node_modules")
13075        );
13076        assert_eq!(
13077            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13078            Path::new("foo")
13079        );
13080        assert_eq!(
13081            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13082            Path::new("foo/bar/baz.js")
13083        );
13084
13085        #[cfg(target_os = "windows")]
13086        {
13087            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13088            assert_eq!(
13089                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13090                Path::new("node_modules")
13091            );
13092            assert_eq!(
13093                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13094                Path::new("foo")
13095            );
13096            assert_eq!(
13097                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13098                Path::new("foo/bar/baz.js")
13099            );
13100        }
13101    }
13102
13103    #[test]
13104    fn test_multi_len_chars_normalization() {
13105        let mut label = CodeLabel {
13106            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13107            runs: vec![(0..6, HighlightId(1))],
13108            filter_range: 0..6,
13109        };
13110        ensure_uniform_list_compatible_label(&mut label);
13111        assert_eq!(
13112            label,
13113            CodeLabel {
13114                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13115                runs: vec![(0..6, HighlightId(1))],
13116                filter_range: 0..6,
13117            }
13118        );
13119    }
13120}