lsp_store.rs

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