lsp_store.rs

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