lsp_store.rs

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