lsp_store.rs

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