lsp_store.rs

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