lsp_store.rs

   1pub mod clangd_ext;
   2pub mod lsp_ext_command;
   3pub mod rust_analyzer_ext;
   4
   5use crate::{
   6    buffer_store::{BufferStore, BufferStoreEvent},
   7    deserialize_code_actions,
   8    environment::ProjectEnvironment,
   9    lsp_command::{self, *},
  10    prettier_store::{self, PrettierStore, PrettierStoreEvent},
  11    project_settings::{LspSettings, ProjectSettings},
  12    project_tree::{AdapterQuery, LanguageServerTree, LaunchDisposition, ProjectTree},
  13    relativize_path, resolve_path,
  14    toolchain_store::{EmptyToolchainStore, ToolchainStoreEvent},
  15    worktree_store::{WorktreeStore, WorktreeStoreEvent},
  16    yarn::YarnPathStore,
  17    CodeAction, Completion, CompletionSource, CoreCompletion, Hover, InlayHint, LspAction,
  18    ProjectItem as _, ProjectPath, ProjectTransaction, ResolveState, Symbol, ToolchainStore,
  19};
  20use anyhow::{anyhow, Context as _, Result};
  21use async_trait::async_trait;
  22use client::{proto, TypedEnvelope};
  23use collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet};
  24use futures::{
  25    future::{join_all, Shared},
  26    select, select_biased,
  27    stream::FuturesUnordered,
  28    AsyncWriteExt, Future, FutureExt, StreamExt,
  29};
  30use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
  31use gpui::{
  32    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
  33    WeakEntity,
  34};
  35use http_client::HttpClient;
  36use itertools::Itertools as _;
  37use language::{
  38    language_settings::{
  39        language_settings, FormatOnSave, Formatter, LanguageSettings, SelectedFormatter,
  40    },
  41    point_to_lsp,
  42    proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
  43    range_from_lsp, range_to_lsp, Bias, 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            let completion_settings = language_settings(
4329                language.as_ref().map(|language| language.name()),
4330                buffer.read(cx).file(),
4331                cx,
4332            )
4333            .completions;
4334            if !completion_settings.lsp {
4335                return Task::ready(Ok(Vec::new()));
4336            }
4337
4338            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
4339                local
4340                    .language_servers_for_buffer(buffer, cx)
4341                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
4342                    .filter(|(adapter, _)| {
4343                        scope
4344                            .as_ref()
4345                            .map(|scope| scope.language_allowed(&adapter.name))
4346                            .unwrap_or(true)
4347                    })
4348                    .map(|(_, server)| server.server_id())
4349                    .collect()
4350            });
4351
4352            let buffer = buffer.clone();
4353            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
4354            let lsp_timeout = if lsp_timeout > 0 {
4355                Some(Duration::from_millis(lsp_timeout))
4356            } else {
4357                None
4358            };
4359            cx.spawn(move |this, mut cx| async move {
4360                let mut tasks = Vec::with_capacity(server_ids.len());
4361                this.update(&mut cx, |lsp_store, cx| {
4362                    for server_id in server_ids {
4363                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
4364                        let lsp_timeout = lsp_timeout
4365                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
4366                        let mut timeout = cx.background_spawn(async move {
4367                            match lsp_timeout {
4368                                Some(lsp_timeout) => {
4369                                    lsp_timeout.await;
4370                                    true
4371                                },
4372                                None => false,
4373                            }
4374                        }).fuse();
4375                        let mut lsp_request = lsp_store.request_lsp(
4376                            buffer.clone(),
4377                            LanguageServerToQuery::Other(server_id),
4378                            GetCompletions {
4379                                position,
4380                                context: context.clone(),
4381                            },
4382                            cx,
4383                        ).fuse();
4384                        let new_task = cx.background_spawn(async move {
4385                            select_biased! {
4386                                response = lsp_request => response,
4387                                timeout_happened = timeout => {
4388                                    if timeout_happened {
4389                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
4390                                        return anyhow::Ok(Vec::new())
4391                                    } else {
4392                                        lsp_request.await
4393                                    }
4394                                },
4395                            }
4396                        });
4397                        tasks.push((lsp_adapter, new_task));
4398                    }
4399                })?;
4400
4401                let mut completions = Vec::new();
4402                for (lsp_adapter, task) in tasks {
4403                    if let Ok(new_completions) = task.await {
4404                        populate_labels_for_completions(
4405                            new_completions,
4406                            language.clone(),
4407                            lsp_adapter,
4408                            &mut completions,
4409                        )
4410                        .await;
4411                    }
4412                }
4413
4414                Ok(completions)
4415            })
4416        } else {
4417            Task::ready(Err(anyhow!("No upstream client or local language server")))
4418        }
4419    }
4420
4421    pub fn resolve_completions(
4422        &self,
4423        buffer: Entity<Buffer>,
4424        completion_indices: Vec<usize>,
4425        completions: Rc<RefCell<Box<[Completion]>>>,
4426        cx: &mut Context<Self>,
4427    ) -> Task<Result<bool>> {
4428        let client = self.upstream_client();
4429
4430        let buffer_id = buffer.read(cx).remote_id();
4431        let buffer_snapshot = buffer.read(cx).snapshot();
4432
4433        cx.spawn(move |this, cx| async move {
4434            let mut did_resolve = false;
4435            if let Some((client, project_id)) = client {
4436                for completion_index in completion_indices {
4437                    let server_id = {
4438                        let completion = &completions.borrow()[completion_index];
4439                        completion.source.server_id()
4440                    };
4441                    if let Some(server_id) = server_id {
4442                        if Self::resolve_completion_remote(
4443                            project_id,
4444                            server_id,
4445                            buffer_id,
4446                            completions.clone(),
4447                            completion_index,
4448                            client.clone(),
4449                        )
4450                        .await
4451                        .log_err()
4452                        .is_some()
4453                        {
4454                            did_resolve = true;
4455                        }
4456                    } else {
4457                        resolve_word_completion(
4458                            &buffer_snapshot,
4459                            &mut completions.borrow_mut()[completion_index],
4460                        );
4461                    }
4462                }
4463            } else {
4464                for completion_index in completion_indices {
4465                    let server_id = {
4466                        let completion = &completions.borrow()[completion_index];
4467                        completion.source.server_id()
4468                    };
4469                    if let Some(server_id) = server_id {
4470                        let server_and_adapter = this
4471                            .read_with(&cx, |lsp_store, _| {
4472                                let server = lsp_store.language_server_for_id(server_id)?;
4473                                let adapter =
4474                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
4475                                Some((server, adapter))
4476                            })
4477                            .ok()
4478                            .flatten();
4479                        let Some((server, adapter)) = server_and_adapter else {
4480                            continue;
4481                        };
4482
4483                        let resolved = Self::resolve_completion_local(
4484                            server,
4485                            &buffer_snapshot,
4486                            completions.clone(),
4487                            completion_index,
4488                        )
4489                        .await
4490                        .log_err()
4491                        .is_some();
4492                        if resolved {
4493                            Self::regenerate_completion_labels(
4494                                adapter,
4495                                &buffer_snapshot,
4496                                completions.clone(),
4497                                completion_index,
4498                            )
4499                            .await
4500                            .log_err();
4501                            did_resolve = true;
4502                        }
4503                    } else {
4504                        resolve_word_completion(
4505                            &buffer_snapshot,
4506                            &mut completions.borrow_mut()[completion_index],
4507                        );
4508                    }
4509                }
4510            }
4511
4512            Ok(did_resolve)
4513        })
4514    }
4515
4516    async fn resolve_completion_local(
4517        server: Arc<lsp::LanguageServer>,
4518        snapshot: &BufferSnapshot,
4519        completions: Rc<RefCell<Box<[Completion]>>>,
4520        completion_index: usize,
4521    ) -> Result<()> {
4522        let server_id = server.server_id();
4523        let can_resolve = server
4524            .capabilities()
4525            .completion_provider
4526            .as_ref()
4527            .and_then(|options| options.resolve_provider)
4528            .unwrap_or(false);
4529        if !can_resolve {
4530            return Ok(());
4531        }
4532
4533        let request = {
4534            let completion = &completions.borrow()[completion_index];
4535            match &completion.source {
4536                CompletionSource::Lsp {
4537                    lsp_completion,
4538                    resolved,
4539                    server_id: completion_server_id,
4540                    ..
4541                } => {
4542                    if *resolved {
4543                        return Ok(());
4544                    }
4545                    anyhow::ensure!(
4546                        server_id == *completion_server_id,
4547                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
4548                    );
4549                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
4550                }
4551                CompletionSource::BufferWord { .. } | CompletionSource::Custom => {
4552                    return Ok(());
4553                }
4554            }
4555        };
4556        let resolved_completion = request.await?;
4557
4558        if let Some(text_edit) = resolved_completion.text_edit.as_ref() {
4559            // Technically we don't have to parse the whole `text_edit`, since the only
4560            // language server we currently use that does update `text_edit` in `completionItem/resolve`
4561            // is `typescript-language-server` and they only update `text_edit.new_text`.
4562            // But we should not rely on that.
4563            let edit = parse_completion_text_edit(text_edit, snapshot);
4564
4565            if let Some((old_range, mut new_text)) = edit {
4566                LineEnding::normalize(&mut new_text);
4567
4568                let mut completions = completions.borrow_mut();
4569                let completion = &mut completions[completion_index];
4570
4571                completion.new_text = new_text;
4572                completion.old_range = old_range;
4573            }
4574        }
4575
4576        let mut completions = completions.borrow_mut();
4577        let completion = &mut completions[completion_index];
4578        if let CompletionSource::Lsp {
4579            lsp_completion,
4580            resolved,
4581            server_id: completion_server_id,
4582            ..
4583        } = &mut completion.source
4584        {
4585            if *resolved {
4586                return Ok(());
4587            }
4588            anyhow::ensure!(
4589                server_id == *completion_server_id,
4590                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
4591            );
4592            *lsp_completion = Box::new(resolved_completion);
4593            *resolved = true;
4594        }
4595        Ok(())
4596    }
4597
4598    async fn regenerate_completion_labels(
4599        adapter: Arc<CachedLspAdapter>,
4600        snapshot: &BufferSnapshot,
4601        completions: Rc<RefCell<Box<[Completion]>>>,
4602        completion_index: usize,
4603    ) -> Result<()> {
4604        let completion_item = completions.borrow()[completion_index]
4605            .source
4606            .lsp_completion(true)
4607            .map(Cow::into_owned);
4608        if let Some(lsp_documentation) = completion_item
4609            .as_ref()
4610            .and_then(|completion_item| completion_item.documentation.clone())
4611        {
4612            let mut completions = completions.borrow_mut();
4613            let completion = &mut completions[completion_index];
4614            completion.documentation = Some(lsp_documentation.into());
4615        } else {
4616            let mut completions = completions.borrow_mut();
4617            let completion = &mut completions[completion_index];
4618            completion.documentation = Some(CompletionDocumentation::Undocumented);
4619        }
4620
4621        let mut new_label = match completion_item {
4622            Some(completion_item) => {
4623                // 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
4624                // So we have to update the label here anyway...
4625                let language = snapshot.language();
4626                match language {
4627                    Some(language) => {
4628                        adapter
4629                            .labels_for_completions(&[completion_item.clone()], language)
4630                            .await?
4631                    }
4632                    None => Vec::new(),
4633                }
4634                .pop()
4635                .flatten()
4636                .unwrap_or_else(|| {
4637                    CodeLabel::fallback_for_completion(
4638                        &completion_item,
4639                        language.map(|language| language.as_ref()),
4640                    )
4641                })
4642            }
4643            None => CodeLabel::plain(
4644                completions.borrow()[completion_index].new_text.clone(),
4645                None,
4646            ),
4647        };
4648        ensure_uniform_list_compatible_label(&mut new_label);
4649
4650        let mut completions = completions.borrow_mut();
4651        let completion = &mut completions[completion_index];
4652        if completion.label.filter_text() == new_label.filter_text() {
4653            completion.label = new_label;
4654        } else {
4655            log::error!(
4656                "Resolved completion changed display label from {} to {}. \
4657                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
4658                completion.label.text(),
4659                new_label.text(),
4660                completion.label.filter_text(),
4661                new_label.filter_text()
4662            );
4663        }
4664
4665        Ok(())
4666    }
4667
4668    async fn resolve_completion_remote(
4669        project_id: u64,
4670        server_id: LanguageServerId,
4671        buffer_id: BufferId,
4672        completions: Rc<RefCell<Box<[Completion]>>>,
4673        completion_index: usize,
4674        client: AnyProtoClient,
4675    ) -> Result<()> {
4676        let lsp_completion = {
4677            let completion = &completions.borrow()[completion_index];
4678            match &completion.source {
4679                CompletionSource::Lsp {
4680                    lsp_completion,
4681                    resolved,
4682                    server_id: completion_server_id,
4683                    ..
4684                } => {
4685                    anyhow::ensure!(
4686                        server_id == *completion_server_id,
4687                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
4688                    );
4689                    if *resolved {
4690                        return Ok(());
4691                    }
4692                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
4693                }
4694                CompletionSource::Custom | CompletionSource::BufferWord { .. } => {
4695                    return Ok(());
4696                }
4697            }
4698        };
4699        let request = proto::ResolveCompletionDocumentation {
4700            project_id,
4701            language_server_id: server_id.0 as u64,
4702            lsp_completion,
4703            buffer_id: buffer_id.into(),
4704        };
4705
4706        let response = client
4707            .request(request)
4708            .await
4709            .context("completion documentation resolve proto request")?;
4710        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
4711
4712        let documentation = if response.documentation.is_empty() {
4713            CompletionDocumentation::Undocumented
4714        } else if response.documentation_is_markdown {
4715            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
4716        } else if response.documentation.lines().count() <= 1 {
4717            CompletionDocumentation::SingleLine(response.documentation.into())
4718        } else {
4719            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
4720        };
4721
4722        let mut completions = completions.borrow_mut();
4723        let completion = &mut completions[completion_index];
4724        completion.documentation = Some(documentation);
4725        if let CompletionSource::Lsp {
4726            lsp_completion,
4727            resolved,
4728            server_id: completion_server_id,
4729            lsp_defaults: _,
4730        } = &mut completion.source
4731        {
4732            if *resolved {
4733                return Ok(());
4734            }
4735            anyhow::ensure!(
4736                server_id == *completion_server_id,
4737                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
4738            );
4739            *lsp_completion = Box::new(resolved_lsp_completion);
4740            *resolved = true;
4741        }
4742
4743        let old_range = response
4744            .old_start
4745            .and_then(deserialize_anchor)
4746            .zip(response.old_end.and_then(deserialize_anchor));
4747        if let Some((old_start, old_end)) = old_range {
4748            if !response.new_text.is_empty() {
4749                completion.new_text = response.new_text;
4750                completion.old_range = old_start..old_end;
4751            }
4752        }
4753
4754        Ok(())
4755    }
4756
4757    pub fn apply_additional_edits_for_completion(
4758        &self,
4759        buffer_handle: Entity<Buffer>,
4760        completions: Rc<RefCell<Box<[Completion]>>>,
4761        completion_index: usize,
4762        push_to_history: bool,
4763        cx: &mut Context<Self>,
4764    ) -> Task<Result<Option<Transaction>>> {
4765        if let Some((client, project_id)) = self.upstream_client() {
4766            let buffer = buffer_handle.read(cx);
4767            let buffer_id = buffer.remote_id();
4768            cx.spawn(move |_, mut cx| async move {
4769                let request = {
4770                    let completion = completions.borrow()[completion_index].clone();
4771                    proto::ApplyCompletionAdditionalEdits {
4772                        project_id,
4773                        buffer_id: buffer_id.into(),
4774                        completion: Some(Self::serialize_completion(&CoreCompletion {
4775                            old_range: completion.old_range,
4776                            new_text: completion.new_text,
4777                            source: completion.source,
4778                        })),
4779                    }
4780                };
4781
4782                if let Some(transaction) = client.request(request).await?.transaction {
4783                    let transaction = language::proto::deserialize_transaction(transaction)?;
4784                    buffer_handle
4785                        .update(&mut cx, |buffer, _| {
4786                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
4787                        })?
4788                        .await?;
4789                    if push_to_history {
4790                        buffer_handle.update(&mut cx, |buffer, _| {
4791                            buffer.push_transaction(transaction.clone(), Instant::now());
4792                        })?;
4793                    }
4794                    Ok(Some(transaction))
4795                } else {
4796                    Ok(None)
4797                }
4798            })
4799        } else {
4800            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
4801                let completion = &completions.borrow()[completion_index];
4802                let server_id = completion.source.server_id()?;
4803                Some(
4804                    self.language_server_for_local_buffer(buffer, server_id, cx)?
4805                        .1
4806                        .clone(),
4807                )
4808            }) else {
4809                return Task::ready(Ok(None));
4810            };
4811            let snapshot = buffer_handle.read(&cx).snapshot();
4812
4813            cx.spawn(move |this, mut cx| async move {
4814                Self::resolve_completion_local(
4815                    server.clone(),
4816                    &snapshot,
4817                    completions.clone(),
4818                    completion_index,
4819                )
4820                .await
4821                .context("resolving completion")?;
4822                let completion = completions.borrow()[completion_index].clone();
4823                let additional_text_edits = completion
4824                    .source
4825                    .lsp_completion(true)
4826                    .as_ref()
4827                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
4828                if let Some(edits) = additional_text_edits {
4829                    let edits = this
4830                        .update(&mut cx, |this, cx| {
4831                            this.as_local_mut().unwrap().edits_from_lsp(
4832                                &buffer_handle,
4833                                edits,
4834                                server.server_id(),
4835                                None,
4836                                cx,
4837                            )
4838                        })?
4839                        .await?;
4840
4841                    buffer_handle.update(&mut cx, |buffer, cx| {
4842                        buffer.finalize_last_transaction();
4843                        buffer.start_transaction();
4844
4845                        for (range, text) in edits {
4846                            let primary = &completion.old_range;
4847                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
4848                                && primary.end.cmp(&range.start, buffer).is_ge();
4849                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
4850                                && range.end.cmp(&primary.end, buffer).is_ge();
4851
4852                            //Skip additional edits which overlap with the primary completion edit
4853                            //https://github.com/zed-industries/zed/pull/1871
4854                            if !start_within && !end_within {
4855                                buffer.edit([(range, text)], None, cx);
4856                            }
4857                        }
4858
4859                        let transaction = if buffer.end_transaction(cx).is_some() {
4860                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
4861                            if !push_to_history {
4862                                buffer.forget_transaction(transaction.id);
4863                            }
4864                            Some(transaction)
4865                        } else {
4866                            None
4867                        };
4868                        Ok(transaction)
4869                    })?
4870                } else {
4871                    Ok(None)
4872                }
4873            })
4874        }
4875    }
4876
4877    pub fn inlay_hints(
4878        &mut self,
4879        buffer_handle: Entity<Buffer>,
4880        range: Range<Anchor>,
4881        cx: &mut Context<Self>,
4882    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
4883        let buffer = buffer_handle.read(cx);
4884        let range_start = range.start;
4885        let range_end = range.end;
4886        let buffer_id = buffer.remote_id().into();
4887        let lsp_request = InlayHints { range };
4888
4889        if let Some((client, project_id)) = self.upstream_client() {
4890            let request = proto::InlayHints {
4891                project_id,
4892                buffer_id,
4893                start: Some(serialize_anchor(&range_start)),
4894                end: Some(serialize_anchor(&range_end)),
4895                version: serialize_version(&buffer_handle.read(cx).version()),
4896            };
4897            cx.spawn(move |project, cx| async move {
4898                let response = client
4899                    .request(request)
4900                    .await
4901                    .context("inlay hints proto request")?;
4902                LspCommand::response_from_proto(
4903                    lsp_request,
4904                    response,
4905                    project.upgrade().ok_or_else(|| anyhow!("No project"))?,
4906                    buffer_handle.clone(),
4907                    cx.clone(),
4908                )
4909                .await
4910                .context("inlay hints proto response conversion")
4911            })
4912        } else {
4913            let lsp_request_task = self.request_lsp(
4914                buffer_handle.clone(),
4915                LanguageServerToQuery::FirstCapable,
4916                lsp_request,
4917                cx,
4918            );
4919            cx.spawn(move |_, mut cx| async move {
4920                buffer_handle
4921                    .update(&mut cx, |buffer, _| {
4922                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
4923                    })?
4924                    .await
4925                    .context("waiting for inlay hint request range edits")?;
4926                lsp_request_task.await.context("inlay hints LSP request")
4927            })
4928        }
4929    }
4930
4931    pub fn signature_help<T: ToPointUtf16>(
4932        &mut self,
4933        buffer: &Entity<Buffer>,
4934        position: T,
4935        cx: &mut Context<Self>,
4936    ) -> Task<Vec<SignatureHelp>> {
4937        let position = position.to_point_utf16(buffer.read(cx));
4938
4939        if let Some((client, upstream_project_id)) = self.upstream_client() {
4940            let request_task = client.request(proto::MultiLspQuery {
4941                buffer_id: buffer.read(cx).remote_id().into(),
4942                version: serialize_version(&buffer.read(cx).version()),
4943                project_id: upstream_project_id,
4944                strategy: Some(proto::multi_lsp_query::Strategy::All(
4945                    proto::AllLanguageServers {},
4946                )),
4947                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
4948                    GetSignatureHelp { position }.to_proto(upstream_project_id, buffer.read(cx)),
4949                )),
4950            });
4951            let buffer = buffer.clone();
4952            cx.spawn(|weak_project, cx| async move {
4953                let Some(project) = weak_project.upgrade() else {
4954                    return Vec::new();
4955                };
4956                join_all(
4957                    request_task
4958                        .await
4959                        .log_err()
4960                        .map(|response| response.responses)
4961                        .unwrap_or_default()
4962                        .into_iter()
4963                        .filter_map(|lsp_response| match lsp_response.response? {
4964                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
4965                                Some(response)
4966                            }
4967                            unexpected => {
4968                                debug_panic!("Unexpected response: {unexpected:?}");
4969                                None
4970                            }
4971                        })
4972                        .map(|signature_response| {
4973                            let response = GetSignatureHelp { position }.response_from_proto(
4974                                signature_response,
4975                                project.clone(),
4976                                buffer.clone(),
4977                                cx.clone(),
4978                            );
4979                            async move { response.await.log_err().flatten() }
4980                        }),
4981                )
4982                .await
4983                .into_iter()
4984                .flatten()
4985                .collect()
4986            })
4987        } else {
4988            let all_actions_task = self.request_multiple_lsp_locally(
4989                buffer,
4990                Some(position),
4991                GetSignatureHelp { position },
4992                cx,
4993            );
4994            cx.spawn(|_, _| async move {
4995                all_actions_task
4996                    .await
4997                    .into_iter()
4998                    .flatten()
4999                    .filter(|help| !help.label.is_empty())
5000                    .collect::<Vec<_>>()
5001            })
5002        }
5003    }
5004
5005    pub fn hover(
5006        &mut self,
5007        buffer: &Entity<Buffer>,
5008        position: PointUtf16,
5009        cx: &mut Context<Self>,
5010    ) -> Task<Vec<Hover>> {
5011        if let Some((client, upstream_project_id)) = self.upstream_client() {
5012            let request_task = client.request(proto::MultiLspQuery {
5013                buffer_id: buffer.read(cx).remote_id().into(),
5014                version: serialize_version(&buffer.read(cx).version()),
5015                project_id: upstream_project_id,
5016                strategy: Some(proto::multi_lsp_query::Strategy::All(
5017                    proto::AllLanguageServers {},
5018                )),
5019                request: Some(proto::multi_lsp_query::Request::GetHover(
5020                    GetHover { position }.to_proto(upstream_project_id, buffer.read(cx)),
5021                )),
5022            });
5023            let buffer = buffer.clone();
5024            cx.spawn(|weak_project, cx| async move {
5025                let Some(project) = weak_project.upgrade() else {
5026                    return Vec::new();
5027                };
5028                join_all(
5029                    request_task
5030                        .await
5031                        .log_err()
5032                        .map(|response| response.responses)
5033                        .unwrap_or_default()
5034                        .into_iter()
5035                        .filter_map(|lsp_response| match lsp_response.response? {
5036                            proto::lsp_response::Response::GetHoverResponse(response) => {
5037                                Some(response)
5038                            }
5039                            unexpected => {
5040                                debug_panic!("Unexpected response: {unexpected:?}");
5041                                None
5042                            }
5043                        })
5044                        .map(|hover_response| {
5045                            let response = GetHover { position }.response_from_proto(
5046                                hover_response,
5047                                project.clone(),
5048                                buffer.clone(),
5049                                cx.clone(),
5050                            );
5051                            async move {
5052                                response
5053                                    .await
5054                                    .log_err()
5055                                    .flatten()
5056                                    .and_then(remove_empty_hover_blocks)
5057                            }
5058                        }),
5059                )
5060                .await
5061                .into_iter()
5062                .flatten()
5063                .collect()
5064            })
5065        } else {
5066            let all_actions_task = self.request_multiple_lsp_locally(
5067                buffer,
5068                Some(position),
5069                GetHover { position },
5070                cx,
5071            );
5072            cx.spawn(|_, _| async move {
5073                all_actions_task
5074                    .await
5075                    .into_iter()
5076                    .filter_map(|hover| remove_empty_hover_blocks(hover?))
5077                    .collect::<Vec<Hover>>()
5078            })
5079        }
5080    }
5081
5082    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
5083        let language_registry = self.languages.clone();
5084
5085        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
5086            let request = upstream_client.request(proto::GetProjectSymbols {
5087                project_id: *project_id,
5088                query: query.to_string(),
5089            });
5090            cx.foreground_executor().spawn(async move {
5091                let response = request.await?;
5092                let mut symbols = Vec::new();
5093                let core_symbols = response
5094                    .symbols
5095                    .into_iter()
5096                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
5097                    .collect::<Vec<_>>();
5098                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
5099                    .await;
5100                Ok(symbols)
5101            })
5102        } else if let Some(local) = self.as_local() {
5103            struct WorkspaceSymbolsResult {
5104                server_id: LanguageServerId,
5105                lsp_adapter: Arc<CachedLspAdapter>,
5106                worktree: WeakEntity<Worktree>,
5107                worktree_abs_path: Arc<Path>,
5108                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
5109            }
5110
5111            let mut requests = Vec::new();
5112            let mut requested_servers = BTreeSet::new();
5113            'next_server: for ((worktree_id, _), server_ids) in local.language_server_ids.iter() {
5114                let Some(worktree_handle) = self
5115                    .worktree_store
5116                    .read(cx)
5117                    .worktree_for_id(*worktree_id, cx)
5118                else {
5119                    continue;
5120                };
5121                let worktree = worktree_handle.read(cx);
5122                if !worktree.is_visible() {
5123                    continue;
5124                }
5125
5126                let mut servers_to_query = server_ids
5127                    .difference(&requested_servers)
5128                    .cloned()
5129                    .collect::<BTreeSet<_>>();
5130                for server_id in &servers_to_query {
5131                    let (lsp_adapter, server) = match local.language_servers.get(server_id) {
5132                        Some(LanguageServerState::Running {
5133                            adapter, server, ..
5134                        }) => (adapter.clone(), server),
5135
5136                        _ => continue 'next_server,
5137                    };
5138                    let worktree_abs_path = worktree.abs_path().clone();
5139                    let worktree_handle = worktree_handle.clone();
5140                    let server_id = server.server_id();
5141                    requests.push(
5142                            server
5143                                .request::<lsp::request::WorkspaceSymbolRequest>(
5144                                    lsp::WorkspaceSymbolParams {
5145                                        query: query.to_string(),
5146                                        ..Default::default()
5147                                    },
5148                                )
5149                                .log_err()
5150                                .map(move |response| {
5151                                    let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response {
5152                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
5153                                            flat_responses.into_iter().map(|lsp_symbol| {
5154                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
5155                                            }).collect::<Vec<_>>()
5156                                        }
5157                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
5158                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
5159                                                let location = match lsp_symbol.location {
5160                                                    OneOf::Left(location) => location,
5161                                                    OneOf::Right(_) => {
5162                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
5163                                                        return None
5164                                                    }
5165                                                };
5166                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
5167                                            }).collect::<Vec<_>>()
5168                                        }
5169                                    }).unwrap_or_default();
5170
5171                                    WorkspaceSymbolsResult {
5172                                        server_id,
5173                                        lsp_adapter,
5174                                        worktree: worktree_handle.downgrade(),
5175                                        worktree_abs_path,
5176                                        lsp_symbols,
5177                                    }
5178                                }),
5179                        );
5180                }
5181                requested_servers.append(&mut servers_to_query);
5182            }
5183
5184            cx.spawn(move |this, mut cx| async move {
5185                let responses = futures::future::join_all(requests).await;
5186                let this = match this.upgrade() {
5187                    Some(this) => this,
5188                    None => return Ok(Vec::new()),
5189                };
5190
5191                let mut symbols = Vec::new();
5192                for result in responses {
5193                    let core_symbols = this.update(&mut cx, |this, cx| {
5194                        result
5195                            .lsp_symbols
5196                            .into_iter()
5197                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
5198                                let abs_path = symbol_location.uri.to_file_path().ok()?;
5199                                let source_worktree = result.worktree.upgrade()?;
5200                                let source_worktree_id = source_worktree.read(cx).id();
5201
5202                                let path;
5203                                let worktree;
5204                                if let Some((tree, rel_path)) =
5205                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
5206                                {
5207                                    worktree = tree;
5208                                    path = rel_path;
5209                                } else {
5210                                    worktree = source_worktree.clone();
5211                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
5212                                }
5213
5214                                let worktree_id = worktree.read(cx).id();
5215                                let project_path = ProjectPath {
5216                                    worktree_id,
5217                                    path: path.into(),
5218                                };
5219                                let signature = this.symbol_signature(&project_path);
5220                                Some(CoreSymbol {
5221                                    source_language_server_id: result.server_id,
5222                                    language_server_name: result.lsp_adapter.name.clone(),
5223                                    source_worktree_id,
5224                                    path: project_path,
5225                                    kind: symbol_kind,
5226                                    name: symbol_name,
5227                                    range: range_from_lsp(symbol_location.range),
5228                                    signature,
5229                                })
5230                            })
5231                            .collect()
5232                    })?;
5233
5234                    populate_labels_for_symbols(
5235                        core_symbols,
5236                        &language_registry,
5237                        Some(result.lsp_adapter),
5238                        &mut symbols,
5239                    )
5240                    .await;
5241                }
5242
5243                Ok(symbols)
5244            })
5245        } else {
5246            Task::ready(Err(anyhow!("No upstream client or local language server")))
5247        }
5248    }
5249
5250    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
5251        let mut summary = DiagnosticSummary::default();
5252        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
5253            summary.error_count += path_summary.error_count;
5254            summary.warning_count += path_summary.warning_count;
5255        }
5256        summary
5257    }
5258
5259    pub fn diagnostic_summaries<'a>(
5260        &'a self,
5261        include_ignored: bool,
5262        cx: &'a App,
5263    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
5264        self.worktree_store
5265            .read(cx)
5266            .visible_worktrees(cx)
5267            .filter_map(|worktree| {
5268                let worktree = worktree.read(cx);
5269                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
5270            })
5271            .flat_map(move |(worktree, summaries)| {
5272                let worktree_id = worktree.id();
5273                summaries
5274                    .iter()
5275                    .filter(move |(path, _)| {
5276                        include_ignored
5277                            || worktree
5278                                .entry_for_path(path.as_ref())
5279                                .map_or(false, |entry| !entry.is_ignored)
5280                    })
5281                    .flat_map(move |(path, summaries)| {
5282                        summaries.iter().map(move |(server_id, summary)| {
5283                            (
5284                                ProjectPath {
5285                                    worktree_id,
5286                                    path: path.clone(),
5287                                },
5288                                *server_id,
5289                                *summary,
5290                            )
5291                        })
5292                    })
5293            })
5294    }
5295
5296    pub fn on_buffer_edited(
5297        &mut self,
5298        buffer: Entity<Buffer>,
5299        cx: &mut Context<Self>,
5300    ) -> Option<()> {
5301        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
5302            Some(
5303                self.as_local()?
5304                    .language_servers_for_buffer(buffer, cx)
5305                    .map(|i| i.1.clone())
5306                    .collect(),
5307            )
5308        })?;
5309
5310        let buffer = buffer.read(cx);
5311        let file = File::from_dyn(buffer.file())?;
5312        let abs_path = file.as_local()?.abs_path(cx);
5313        let uri = lsp::Url::from_file_path(abs_path).unwrap();
5314        let next_snapshot = buffer.text_snapshot();
5315        for language_server in language_servers {
5316            let language_server = language_server.clone();
5317
5318            let buffer_snapshots = self
5319                .as_local_mut()
5320                .unwrap()
5321                .buffer_snapshots
5322                .get_mut(&buffer.remote_id())
5323                .and_then(|m| m.get_mut(&language_server.server_id()))?;
5324            let previous_snapshot = buffer_snapshots.last()?;
5325
5326            let build_incremental_change = || {
5327                buffer
5328                    .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version())
5329                    .map(|edit| {
5330                        let edit_start = edit.new.start.0;
5331                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
5332                        let new_text = next_snapshot
5333                            .text_for_range(edit.new.start.1..edit.new.end.1)
5334                            .collect();
5335                        lsp::TextDocumentContentChangeEvent {
5336                            range: Some(lsp::Range::new(
5337                                point_to_lsp(edit_start),
5338                                point_to_lsp(edit_end),
5339                            )),
5340                            range_length: None,
5341                            text: new_text,
5342                        }
5343                    })
5344                    .collect()
5345            };
5346
5347            let document_sync_kind = language_server
5348                .capabilities()
5349                .text_document_sync
5350                .as_ref()
5351                .and_then(|sync| match sync {
5352                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
5353                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
5354                });
5355
5356            let content_changes: Vec<_> = match document_sync_kind {
5357                Some(lsp::TextDocumentSyncKind::FULL) => {
5358                    vec![lsp::TextDocumentContentChangeEvent {
5359                        range: None,
5360                        range_length: None,
5361                        text: next_snapshot.text(),
5362                    }]
5363                }
5364                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
5365                _ => {
5366                    #[cfg(any(test, feature = "test-support"))]
5367                    {
5368                        build_incremental_change()
5369                    }
5370
5371                    #[cfg(not(any(test, feature = "test-support")))]
5372                    {
5373                        continue;
5374                    }
5375                }
5376            };
5377
5378            let next_version = previous_snapshot.version + 1;
5379            buffer_snapshots.push(LspBufferSnapshot {
5380                version: next_version,
5381                snapshot: next_snapshot.clone(),
5382            });
5383
5384            language_server
5385                .notify::<lsp::notification::DidChangeTextDocument>(
5386                    &lsp::DidChangeTextDocumentParams {
5387                        text_document: lsp::VersionedTextDocumentIdentifier::new(
5388                            uri.clone(),
5389                            next_version,
5390                        ),
5391                        content_changes,
5392                    },
5393                )
5394                .log_err();
5395        }
5396
5397        None
5398    }
5399
5400    pub fn on_buffer_saved(
5401        &mut self,
5402        buffer: Entity<Buffer>,
5403        cx: &mut Context<Self>,
5404    ) -> Option<()> {
5405        let file = File::from_dyn(buffer.read(cx).file())?;
5406        let worktree_id = file.worktree_id(cx);
5407        let abs_path = file.as_local()?.abs_path(cx);
5408        let text_document = lsp::TextDocumentIdentifier {
5409            uri: lsp::Url::from_file_path(abs_path).log_err()?,
5410        };
5411        let local = self.as_local()?;
5412
5413        for server in local.language_servers_for_worktree(worktree_id) {
5414            if let Some(include_text) = include_text(server.as_ref()) {
5415                let text = if include_text {
5416                    Some(buffer.read(cx).text())
5417                } else {
5418                    None
5419                };
5420                server
5421                    .notify::<lsp::notification::DidSaveTextDocument>(
5422                        &lsp::DidSaveTextDocumentParams {
5423                            text_document: text_document.clone(),
5424                            text,
5425                        },
5426                    )
5427                    .log_err();
5428            }
5429        }
5430
5431        let language_servers = buffer.update(cx, |buffer, cx| {
5432            local.language_server_ids_for_buffer(buffer, cx)
5433        });
5434        for language_server_id in language_servers {
5435            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
5436        }
5437
5438        None
5439    }
5440
5441    pub(crate) async fn refresh_workspace_configurations(
5442        this: &WeakEntity<Self>,
5443        fs: Arc<dyn Fs>,
5444        mut cx: AsyncApp,
5445    ) {
5446        maybe!(async move {
5447            let servers = this
5448                .update(&mut cx, |this, cx| {
5449                    let Some(local) = this.as_local() else {
5450                        return Vec::default();
5451                    };
5452                    local
5453                        .language_server_ids
5454                        .iter()
5455                        .flat_map(|((worktree_id, _), server_ids)| {
5456                            let worktree = this
5457                                .worktree_store
5458                                .read(cx)
5459                                .worktree_for_id(*worktree_id, cx);
5460                            let delegate = worktree.map(|worktree| {
5461                                LocalLspAdapterDelegate::new(
5462                                    local.languages.clone(),
5463                                    &local.environment,
5464                                    cx.weak_entity(),
5465                                    &worktree,
5466                                    local.http_client.clone(),
5467                                    local.fs.clone(),
5468                                    cx,
5469                                )
5470                            });
5471
5472                            server_ids.iter().filter_map(move |server_id| {
5473                                let states = local.language_servers.get(server_id)?;
5474
5475                                match states {
5476                                    LanguageServerState::Starting { .. } => None,
5477                                    LanguageServerState::Running {
5478                                        adapter, server, ..
5479                                    } => Some((
5480                                        adapter.adapter.clone(),
5481                                        server.clone(),
5482                                        delegate.clone()? as Arc<dyn LspAdapterDelegate>,
5483                                    )),
5484                                }
5485                            })
5486                        })
5487                        .collect::<Vec<_>>()
5488                })
5489                .ok()?;
5490
5491            let toolchain_store = this
5492                .update(&mut cx, |this, cx| this.toolchain_store(cx))
5493                .ok()?;
5494            for (adapter, server, delegate) in servers {
5495                let settings = adapter
5496                    .workspace_configuration(
5497                        fs.as_ref(),
5498                        &delegate,
5499                        toolchain_store.clone(),
5500                        &mut cx,
5501                    )
5502                    .await
5503                    .ok()?;
5504
5505                server
5506                    .notify::<lsp::notification::DidChangeConfiguration>(
5507                        &lsp::DidChangeConfigurationParams { settings },
5508                    )
5509                    .ok();
5510            }
5511            Some(())
5512        })
5513        .await;
5514    }
5515
5516    fn toolchain_store(&self, cx: &App) -> Arc<dyn LanguageToolchainStore> {
5517        if let Some(toolchain_store) = self.toolchain_store.as_ref() {
5518            toolchain_store.read(cx).as_language_toolchain_store()
5519        } else {
5520            Arc::new(EmptyToolchainStore)
5521        }
5522    }
5523    fn maintain_workspace_config(
5524        fs: Arc<dyn Fs>,
5525        external_refresh_requests: watch::Receiver<()>,
5526        cx: &mut Context<Self>,
5527    ) -> Task<Result<()>> {
5528        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
5529        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
5530
5531        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
5532            *settings_changed_tx.borrow_mut() = ();
5533        });
5534
5535        let mut joint_future =
5536            futures::stream::select(settings_changed_rx, external_refresh_requests);
5537        cx.spawn(move |this, cx| async move {
5538            while let Some(()) = joint_future.next().await {
5539                Self::refresh_workspace_configurations(&this, fs.clone(), cx.clone()).await;
5540            }
5541
5542            drop(settings_observation);
5543            anyhow::Ok(())
5544        })
5545    }
5546
5547    pub fn language_servers_for_local_buffer<'a>(
5548        &'a self,
5549        buffer: &Buffer,
5550        cx: &mut App,
5551    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
5552        let local = self.as_local();
5553        let language_server_ids = local
5554            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
5555            .unwrap_or_default();
5556
5557        language_server_ids
5558            .into_iter()
5559            .filter_map(
5560                move |server_id| match local?.language_servers.get(&server_id)? {
5561                    LanguageServerState::Running {
5562                        adapter, server, ..
5563                    } => Some((adapter, server)),
5564                    _ => None,
5565                },
5566            )
5567    }
5568
5569    pub fn language_server_for_local_buffer<'a>(
5570        &'a self,
5571        buffer: &'a Buffer,
5572        server_id: LanguageServerId,
5573        cx: &'a mut App,
5574    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
5575        self.as_local()?
5576            .language_servers_for_buffer(buffer, cx)
5577            .find(|(_, s)| s.server_id() == server_id)
5578    }
5579
5580    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
5581        self.diagnostic_summaries.remove(&id_to_remove);
5582        if let Some(local) = self.as_local_mut() {
5583            let to_remove = local.remove_worktree(id_to_remove, cx);
5584            for server in to_remove {
5585                self.language_server_statuses.remove(&server);
5586            }
5587        }
5588    }
5589
5590    pub fn shared(
5591        &mut self,
5592        project_id: u64,
5593        downstream_client: AnyProtoClient,
5594        _: &mut Context<Self>,
5595    ) {
5596        self.downstream_client = Some((downstream_client.clone(), project_id));
5597
5598        for (server_id, status) in &self.language_server_statuses {
5599            downstream_client
5600                .send(proto::StartLanguageServer {
5601                    project_id,
5602                    server: Some(proto::LanguageServer {
5603                        id: server_id.0 as u64,
5604                        name: status.name.clone(),
5605                        worktree_id: None,
5606                    }),
5607                })
5608                .log_err();
5609        }
5610    }
5611
5612    pub fn disconnected_from_host(&mut self) {
5613        self.downstream_client.take();
5614    }
5615
5616    pub fn disconnected_from_ssh_remote(&mut self) {
5617        if let LspStoreMode::Remote(RemoteLspStore {
5618            upstream_client, ..
5619        }) = &mut self.mode
5620        {
5621            upstream_client.take();
5622        }
5623    }
5624
5625    pub(crate) fn set_language_server_statuses_from_proto(
5626        &mut self,
5627        language_servers: Vec<proto::LanguageServer>,
5628    ) {
5629        self.language_server_statuses = language_servers
5630            .into_iter()
5631            .map(|server| {
5632                (
5633                    LanguageServerId(server.id as usize),
5634                    LanguageServerStatus {
5635                        name: server.name,
5636                        pending_work: Default::default(),
5637                        has_pending_diagnostic_updates: false,
5638                        progress_tokens: Default::default(),
5639                    },
5640                )
5641            })
5642            .collect();
5643    }
5644
5645    fn register_local_language_server(
5646        &mut self,
5647        worktree: Entity<Worktree>,
5648        language_server_name: LanguageServerName,
5649        language_server_id: LanguageServerId,
5650        cx: &mut App,
5651    ) {
5652        let Some(local) = self.as_local_mut() else {
5653            return;
5654        };
5655        let worktree_id = worktree.read(cx).id();
5656        let path = ProjectPath {
5657            worktree_id,
5658            path: Arc::from("".as_ref()),
5659        };
5660        let delegate = LocalLspAdapterDelegate::from_local_lsp(local, &worktree, cx);
5661        local.lsp_tree.update(cx, |this, cx| {
5662            for node in this.get(
5663                path,
5664                AdapterQuery::Adapter(&language_server_name),
5665                delegate,
5666                cx,
5667            ) {
5668                node.server_id_or_init(|disposition| {
5669                    assert_eq!(disposition.server_name, &language_server_name);
5670
5671                    language_server_id
5672                });
5673            }
5674        });
5675        local
5676            .language_server_ids
5677            .entry((worktree_id, language_server_name))
5678            .or_default()
5679            .insert(language_server_id);
5680    }
5681
5682    pub fn update_diagnostic_entries(
5683        &mut self,
5684        server_id: LanguageServerId,
5685        abs_path: PathBuf,
5686        version: Option<i32>,
5687        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
5688        cx: &mut Context<Self>,
5689    ) -> Result<(), anyhow::Error> {
5690        let Some((worktree, relative_path)) =
5691            self.worktree_store.read(cx).find_worktree(&abs_path, cx)
5692        else {
5693            log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
5694            return Ok(());
5695        };
5696
5697        let project_path = ProjectPath {
5698            worktree_id: worktree.read(cx).id(),
5699            path: relative_path.into(),
5700        };
5701
5702        if let Some(buffer) = self.buffer_store.read(cx).get_by_path(&project_path, cx) {
5703            self.as_local_mut().unwrap().update_buffer_diagnostics(
5704                &buffer,
5705                server_id,
5706                version,
5707                diagnostics.clone(),
5708                cx,
5709            )?;
5710        }
5711
5712        let updated = worktree.update(cx, |worktree, cx| {
5713            self.update_worktree_diagnostics(
5714                worktree.id(),
5715                server_id,
5716                project_path.path.clone(),
5717                diagnostics,
5718                cx,
5719            )
5720        })?;
5721        if updated {
5722            cx.emit(LspStoreEvent::DiagnosticsUpdated {
5723                language_server_id: server_id,
5724                path: project_path,
5725            })
5726        }
5727        Ok(())
5728    }
5729
5730    fn update_worktree_diagnostics(
5731        &mut self,
5732        worktree_id: WorktreeId,
5733        server_id: LanguageServerId,
5734        worktree_path: Arc<Path>,
5735        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
5736        _: &mut Context<Worktree>,
5737    ) -> Result<bool> {
5738        let local = match &mut self.mode {
5739            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
5740            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
5741        };
5742
5743        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
5744        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
5745        let summaries_by_server_id = summaries_for_tree.entry(worktree_path.clone()).or_default();
5746
5747        let old_summary = summaries_by_server_id
5748            .remove(&server_id)
5749            .unwrap_or_default();
5750
5751        let new_summary = DiagnosticSummary::new(&diagnostics);
5752        if new_summary.is_empty() {
5753            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&worktree_path) {
5754                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
5755                    diagnostics_by_server_id.remove(ix);
5756                }
5757                if diagnostics_by_server_id.is_empty() {
5758                    diagnostics_for_tree.remove(&worktree_path);
5759                }
5760            }
5761        } else {
5762            summaries_by_server_id.insert(server_id, new_summary);
5763            let diagnostics_by_server_id = diagnostics_for_tree
5764                .entry(worktree_path.clone())
5765                .or_default();
5766            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
5767                Ok(ix) => {
5768                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
5769                }
5770                Err(ix) => {
5771                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
5772                }
5773            }
5774        }
5775
5776        if !old_summary.is_empty() || !new_summary.is_empty() {
5777            if let Some((downstream_client, project_id)) = &self.downstream_client {
5778                downstream_client
5779                    .send(proto::UpdateDiagnosticSummary {
5780                        project_id: *project_id,
5781                        worktree_id: worktree_id.to_proto(),
5782                        summary: Some(proto::DiagnosticSummary {
5783                            path: worktree_path.to_proto(),
5784                            language_server_id: server_id.0 as u64,
5785                            error_count: new_summary.error_count as u32,
5786                            warning_count: new_summary.warning_count as u32,
5787                        }),
5788                    })
5789                    .log_err();
5790            }
5791        }
5792
5793        Ok(!old_summary.is_empty() || !new_summary.is_empty())
5794    }
5795
5796    pub fn open_buffer_for_symbol(
5797        &mut self,
5798        symbol: &Symbol,
5799        cx: &mut Context<Self>,
5800    ) -> Task<Result<Entity<Buffer>>> {
5801        if let Some((client, project_id)) = self.upstream_client() {
5802            let request = client.request(proto::OpenBufferForSymbol {
5803                project_id,
5804                symbol: Some(Self::serialize_symbol(symbol)),
5805            });
5806            cx.spawn(move |this, mut cx| async move {
5807                let response = request.await?;
5808                let buffer_id = BufferId::new(response.buffer_id)?;
5809                this.update(&mut cx, |this, cx| {
5810                    this.wait_for_remote_buffer(buffer_id, cx)
5811                })?
5812                .await
5813            })
5814        } else if let Some(local) = self.as_local() {
5815            let Some(language_server_id) = local
5816                .language_server_ids
5817                .get(&(
5818                    symbol.source_worktree_id,
5819                    symbol.language_server_name.clone(),
5820                ))
5821                .and_then(|ids| {
5822                    ids.contains(&symbol.source_language_server_id)
5823                        .then_some(symbol.source_language_server_id)
5824                })
5825            else {
5826                return Task::ready(Err(anyhow!(
5827                    "language server for worktree and language not found"
5828                )));
5829            };
5830
5831            let worktree_abs_path = if let Some(worktree_abs_path) = self
5832                .worktree_store
5833                .read(cx)
5834                .worktree_for_id(symbol.path.worktree_id, cx)
5835                .map(|worktree| worktree.read(cx).abs_path())
5836            {
5837                worktree_abs_path
5838            } else {
5839                return Task::ready(Err(anyhow!("worktree not found for symbol")));
5840            };
5841
5842            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
5843            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
5844                uri
5845            } else {
5846                return Task::ready(Err(anyhow!("invalid symbol path")));
5847            };
5848
5849            self.open_local_buffer_via_lsp(
5850                symbol_uri,
5851                language_server_id,
5852                symbol.language_server_name.clone(),
5853                cx,
5854            )
5855        } else {
5856            Task::ready(Err(anyhow!("no upstream client or local store")))
5857        }
5858    }
5859
5860    pub fn open_local_buffer_via_lsp(
5861        &mut self,
5862        mut abs_path: lsp::Url,
5863        language_server_id: LanguageServerId,
5864        language_server_name: LanguageServerName,
5865        cx: &mut Context<Self>,
5866    ) -> Task<Result<Entity<Buffer>>> {
5867        cx.spawn(move |lsp_store, mut cx| async move {
5868            // Escape percent-encoded string.
5869            let current_scheme = abs_path.scheme().to_owned();
5870            let _ = abs_path.set_scheme("file");
5871
5872            let abs_path = abs_path
5873                .to_file_path()
5874                .map_err(|_| anyhow!("can't convert URI to path"))?;
5875            let p = abs_path.clone();
5876            let yarn_worktree = lsp_store
5877                .update(&mut cx, move |lsp_store, cx| match lsp_store.as_local() {
5878                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
5879                        cx.spawn(|this, mut cx| async move {
5880                            let t = this
5881                                .update(&mut cx, |this, cx| {
5882                                    this.process_path(&p, &current_scheme, cx)
5883                                })
5884                                .ok()?;
5885                            t.await
5886                        })
5887                    }),
5888                    None => Task::ready(None),
5889                })?
5890                .await;
5891            let (worktree_root_target, known_relative_path) =
5892                if let Some((zip_root, relative_path)) = yarn_worktree {
5893                    (zip_root, Some(relative_path))
5894                } else {
5895                    (Arc::<Path>::from(abs_path.as_path()), None)
5896                };
5897            let (worktree, relative_path) = if let Some(result) =
5898                lsp_store.update(&mut cx, |lsp_store, cx| {
5899                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
5900                        worktree_store.find_worktree(&worktree_root_target, cx)
5901                    })
5902                })? {
5903                let relative_path =
5904                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
5905                (result.0, relative_path)
5906            } else {
5907                let worktree = lsp_store
5908                    .update(&mut cx, |lsp_store, cx| {
5909                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
5910                            worktree_store.create_worktree(&worktree_root_target, false, cx)
5911                        })
5912                    })?
5913                    .await?;
5914                if worktree.update(&mut cx, |worktree, _| worktree.is_local())? {
5915                    lsp_store
5916                        .update(&mut cx, |lsp_store, cx| {
5917                            lsp_store.register_local_language_server(
5918                                worktree.clone(),
5919                                language_server_name,
5920                                language_server_id,
5921                                cx,
5922                            )
5923                        })
5924                        .ok();
5925                }
5926                let worktree_root = worktree.update(&mut cx, |worktree, _| worktree.abs_path())?;
5927                let relative_path = if let Some(known_path) = known_relative_path {
5928                    known_path
5929                } else {
5930                    abs_path.strip_prefix(worktree_root)?.into()
5931                };
5932                (worktree, relative_path)
5933            };
5934            let project_path = ProjectPath {
5935                worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?,
5936                path: relative_path,
5937            };
5938            lsp_store
5939                .update(&mut cx, |lsp_store, cx| {
5940                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
5941                        buffer_store.open_buffer(project_path, cx)
5942                    })
5943                })?
5944                .await
5945        })
5946    }
5947
5948    fn request_multiple_lsp_locally<P, R>(
5949        &mut self,
5950        buffer: &Entity<Buffer>,
5951        position: Option<P>,
5952        request: R,
5953        cx: &mut Context<'_, Self>,
5954    ) -> Task<Vec<R::Response>>
5955    where
5956        P: ToOffset,
5957        R: LspCommand + Clone,
5958        <R::LspRequest as lsp::request::Request>::Result: Send,
5959        <R::LspRequest as lsp::request::Request>::Params: Send,
5960    {
5961        let Some(local) = self.as_local() else {
5962            return Task::ready(Vec::new());
5963        };
5964
5965        let snapshot = buffer.read(cx).snapshot();
5966        let scope = position.and_then(|position| snapshot.language_scope_at(position));
5967
5968        let server_ids = buffer.update(cx, |buffer, cx| {
5969            local
5970                .language_servers_for_buffer(buffer, cx)
5971                .filter(|(adapter, _)| {
5972                    scope
5973                        .as_ref()
5974                        .map(|scope| scope.language_allowed(&adapter.name))
5975                        .unwrap_or(true)
5976                })
5977                .map(|(_, server)| server.server_id())
5978                .collect::<Vec<_>>()
5979        });
5980
5981        let mut response_results = server_ids
5982            .into_iter()
5983            .map(|server_id| {
5984                self.request_lsp(
5985                    buffer.clone(),
5986                    LanguageServerToQuery::Other(server_id),
5987                    request.clone(),
5988                    cx,
5989                )
5990            })
5991            .collect::<FuturesUnordered<_>>();
5992
5993        cx.spawn(|_, _| async move {
5994            let mut responses = Vec::with_capacity(response_results.len());
5995            while let Some(response_result) = response_results.next().await {
5996                if let Some(response) = response_result.log_err() {
5997                    responses.push(response);
5998                }
5999            }
6000            responses
6001        })
6002    }
6003
6004    async fn handle_lsp_command<T: LspCommand>(
6005        this: Entity<Self>,
6006        envelope: TypedEnvelope<T::ProtoRequest>,
6007        mut cx: AsyncApp,
6008    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
6009    where
6010        <T::LspRequest as lsp::request::Request>::Params: Send,
6011        <T::LspRequest as lsp::request::Request>::Result: Send,
6012    {
6013        let sender_id = envelope.original_sender_id().unwrap_or_default();
6014        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
6015        let buffer_handle = this.update(&mut cx, |this, cx| {
6016            this.buffer_store.read(cx).get_existing(buffer_id)
6017        })??;
6018        let request = T::from_proto(
6019            envelope.payload,
6020            this.clone(),
6021            buffer_handle.clone(),
6022            cx.clone(),
6023        )
6024        .await?;
6025        let response = this
6026            .update(&mut cx, |this, cx| {
6027                this.request_lsp(
6028                    buffer_handle.clone(),
6029                    LanguageServerToQuery::FirstCapable,
6030                    request,
6031                    cx,
6032                )
6033            })?
6034            .await?;
6035        this.update(&mut cx, |this, cx| {
6036            Ok(T::response_to_proto(
6037                response,
6038                this,
6039                sender_id,
6040                &buffer_handle.read(cx).version(),
6041                cx,
6042            ))
6043        })?
6044    }
6045
6046    async fn handle_multi_lsp_query(
6047        this: Entity<Self>,
6048        envelope: TypedEnvelope<proto::MultiLspQuery>,
6049        mut cx: AsyncApp,
6050    ) -> Result<proto::MultiLspQueryResponse> {
6051        let response_from_ssh = this.update(&mut cx, |this, _| {
6052            let (upstream_client, project_id) = this.upstream_client()?;
6053            let mut payload = envelope.payload.clone();
6054            payload.project_id = project_id;
6055
6056            Some(upstream_client.request(payload))
6057        })?;
6058        if let Some(response_from_ssh) = response_from_ssh {
6059            return response_from_ssh.await;
6060        }
6061
6062        let sender_id = envelope.original_sender_id().unwrap_or_default();
6063        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6064        let version = deserialize_version(&envelope.payload.version);
6065        let buffer = this.update(&mut cx, |this, cx| {
6066            this.buffer_store.read(cx).get_existing(buffer_id)
6067        })??;
6068        buffer
6069            .update(&mut cx, |buffer, _| {
6070                buffer.wait_for_version(version.clone())
6071            })?
6072            .await?;
6073        let buffer_version = buffer.update(&mut cx, |buffer, _| buffer.version())?;
6074        match envelope
6075            .payload
6076            .strategy
6077            .context("invalid request without the strategy")?
6078        {
6079            proto::multi_lsp_query::Strategy::All(_) => {
6080                // currently, there's only one multiple language servers query strategy,
6081                // so just ensure it's specified correctly
6082            }
6083        }
6084        match envelope.payload.request {
6085            Some(proto::multi_lsp_query::Request::GetHover(get_hover)) => {
6086                let get_hover =
6087                    GetHover::from_proto(get_hover, this.clone(), buffer.clone(), cx.clone())
6088                        .await?;
6089                let all_hovers = this
6090                    .update(&mut cx, |this, cx| {
6091                        this.request_multiple_lsp_locally(
6092                            &buffer,
6093                            Some(get_hover.position),
6094                            get_hover,
6095                            cx,
6096                        )
6097                    })?
6098                    .await
6099                    .into_iter()
6100                    .filter_map(|hover| remove_empty_hover_blocks(hover?));
6101                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6102                    responses: all_hovers
6103                        .map(|hover| proto::LspResponse {
6104                            response: Some(proto::lsp_response::Response::GetHoverResponse(
6105                                GetHover::response_to_proto(
6106                                    Some(hover),
6107                                    project,
6108                                    sender_id,
6109                                    &buffer_version,
6110                                    cx,
6111                                ),
6112                            )),
6113                        })
6114                        .collect(),
6115                })
6116            }
6117            Some(proto::multi_lsp_query::Request::GetCodeActions(get_code_actions)) => {
6118                let get_code_actions = GetCodeActions::from_proto(
6119                    get_code_actions,
6120                    this.clone(),
6121                    buffer.clone(),
6122                    cx.clone(),
6123                )
6124                .await?;
6125
6126                let all_actions = this
6127                    .update(&mut cx, |project, cx| {
6128                        project.request_multiple_lsp_locally(
6129                            &buffer,
6130                            Some(get_code_actions.range.start),
6131                            get_code_actions,
6132                            cx,
6133                        )
6134                    })?
6135                    .await
6136                    .into_iter();
6137
6138                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6139                    responses: all_actions
6140                        .map(|code_actions| proto::LspResponse {
6141                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
6142                                GetCodeActions::response_to_proto(
6143                                    code_actions,
6144                                    project,
6145                                    sender_id,
6146                                    &buffer_version,
6147                                    cx,
6148                                ),
6149                            )),
6150                        })
6151                        .collect(),
6152                })
6153            }
6154            Some(proto::multi_lsp_query::Request::GetSignatureHelp(get_signature_help)) => {
6155                let get_signature_help = GetSignatureHelp::from_proto(
6156                    get_signature_help,
6157                    this.clone(),
6158                    buffer.clone(),
6159                    cx.clone(),
6160                )
6161                .await?;
6162
6163                let all_signatures = this
6164                    .update(&mut cx, |project, cx| {
6165                        project.request_multiple_lsp_locally(
6166                            &buffer,
6167                            Some(get_signature_help.position),
6168                            get_signature_help,
6169                            cx,
6170                        )
6171                    })?
6172                    .await
6173                    .into_iter();
6174
6175                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6176                    responses: all_signatures
6177                        .map(|signature_help| proto::LspResponse {
6178                            response: Some(
6179                                proto::lsp_response::Response::GetSignatureHelpResponse(
6180                                    GetSignatureHelp::response_to_proto(
6181                                        signature_help,
6182                                        project,
6183                                        sender_id,
6184                                        &buffer_version,
6185                                        cx,
6186                                    ),
6187                                ),
6188                            ),
6189                        })
6190                        .collect(),
6191                })
6192            }
6193            None => anyhow::bail!("empty multi lsp query request"),
6194        }
6195    }
6196
6197    async fn handle_apply_code_action(
6198        this: Entity<Self>,
6199        envelope: TypedEnvelope<proto::ApplyCodeAction>,
6200        mut cx: AsyncApp,
6201    ) -> Result<proto::ApplyCodeActionResponse> {
6202        let sender_id = envelope.original_sender_id().unwrap_or_default();
6203        let action = Self::deserialize_code_action(
6204            envelope
6205                .payload
6206                .action
6207                .ok_or_else(|| anyhow!("invalid action"))?,
6208        )?;
6209        let apply_code_action = this.update(&mut cx, |this, cx| {
6210            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6211            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6212            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
6213        })??;
6214
6215        let project_transaction = apply_code_action.await?;
6216        let project_transaction = this.update(&mut cx, |this, cx| {
6217            this.buffer_store.update(cx, |buffer_store, cx| {
6218                buffer_store.serialize_project_transaction_for_peer(
6219                    project_transaction,
6220                    sender_id,
6221                    cx,
6222                )
6223            })
6224        })?;
6225        Ok(proto::ApplyCodeActionResponse {
6226            transaction: Some(project_transaction),
6227        })
6228    }
6229
6230    async fn handle_register_buffer_with_language_servers(
6231        this: Entity<Self>,
6232        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
6233        mut cx: AsyncApp,
6234    ) -> Result<proto::Ack> {
6235        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6236        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
6237        this.update(&mut cx, |this, cx| {
6238            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
6239                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
6240                    project_id: upstream_project_id,
6241                    buffer_id: buffer_id.to_proto(),
6242                });
6243            }
6244
6245            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
6246                anyhow::bail!("buffer is not open");
6247            };
6248
6249            let handle = this.register_buffer_with_language_servers(&buffer, false, cx);
6250            this.buffer_store().update(cx, |buffer_store, _| {
6251                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
6252            });
6253
6254            Ok(())
6255        })??;
6256        Ok(proto::Ack {})
6257    }
6258
6259    async fn handle_rename_project_entry(
6260        this: Entity<Self>,
6261        envelope: TypedEnvelope<proto::RenameProjectEntry>,
6262        mut cx: AsyncApp,
6263    ) -> Result<proto::ProjectEntryResponse> {
6264        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
6265        let (worktree_id, worktree, old_path, is_dir) = this
6266            .update(&mut cx, |this, cx| {
6267                this.worktree_store
6268                    .read(cx)
6269                    .worktree_and_entry_for_id(entry_id, cx)
6270                    .map(|(worktree, entry)| {
6271                        (
6272                            worktree.read(cx).id(),
6273                            worktree,
6274                            entry.path.clone(),
6275                            entry.is_dir(),
6276                        )
6277                    })
6278            })?
6279            .ok_or_else(|| anyhow!("worktree not found"))?;
6280        let (old_abs_path, new_abs_path) = {
6281            let root_path = worktree.update(&mut cx, |this, _| this.abs_path())?;
6282            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
6283            (root_path.join(&old_path), root_path.join(&new_path))
6284        };
6285
6286        Self::will_rename_entry(
6287            this.downgrade(),
6288            worktree_id,
6289            &old_abs_path,
6290            &new_abs_path,
6291            is_dir,
6292            cx.clone(),
6293        )
6294        .await;
6295        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
6296        this.update(&mut cx, |this, _| {
6297            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
6298        })
6299        .ok();
6300        response
6301    }
6302
6303    async fn handle_update_diagnostic_summary(
6304        this: Entity<Self>,
6305        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
6306        mut cx: AsyncApp,
6307    ) -> Result<()> {
6308        this.update(&mut cx, |this, cx| {
6309            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
6310            if let Some(message) = envelope.payload.summary {
6311                let project_path = ProjectPath {
6312                    worktree_id,
6313                    path: Arc::<Path>::from_proto(message.path),
6314                };
6315                let path = project_path.path.clone();
6316                let server_id = LanguageServerId(message.language_server_id as usize);
6317                let summary = DiagnosticSummary {
6318                    error_count: message.error_count as usize,
6319                    warning_count: message.warning_count as usize,
6320                };
6321
6322                if summary.is_empty() {
6323                    if let Some(worktree_summaries) =
6324                        this.diagnostic_summaries.get_mut(&worktree_id)
6325                    {
6326                        if let Some(summaries) = worktree_summaries.get_mut(&path) {
6327                            summaries.remove(&server_id);
6328                            if summaries.is_empty() {
6329                                worktree_summaries.remove(&path);
6330                            }
6331                        }
6332                    }
6333                } else {
6334                    this.diagnostic_summaries
6335                        .entry(worktree_id)
6336                        .or_default()
6337                        .entry(path)
6338                        .or_default()
6339                        .insert(server_id, summary);
6340                }
6341                if let Some((downstream_client, project_id)) = &this.downstream_client {
6342                    downstream_client
6343                        .send(proto::UpdateDiagnosticSummary {
6344                            project_id: *project_id,
6345                            worktree_id: worktree_id.to_proto(),
6346                            summary: Some(proto::DiagnosticSummary {
6347                                path: project_path.path.as_ref().to_proto(),
6348                                language_server_id: server_id.0 as u64,
6349                                error_count: summary.error_count as u32,
6350                                warning_count: summary.warning_count as u32,
6351                            }),
6352                        })
6353                        .log_err();
6354                }
6355                cx.emit(LspStoreEvent::DiagnosticsUpdated {
6356                    language_server_id: LanguageServerId(message.language_server_id as usize),
6357                    path: project_path,
6358                });
6359            }
6360            Ok(())
6361        })?
6362    }
6363
6364    async fn handle_start_language_server(
6365        this: Entity<Self>,
6366        envelope: TypedEnvelope<proto::StartLanguageServer>,
6367        mut cx: AsyncApp,
6368    ) -> Result<()> {
6369        let server = envelope
6370            .payload
6371            .server
6372            .ok_or_else(|| anyhow!("invalid server"))?;
6373
6374        this.update(&mut cx, |this, cx| {
6375            let server_id = LanguageServerId(server.id as usize);
6376            this.language_server_statuses.insert(
6377                server_id,
6378                LanguageServerStatus {
6379                    name: server.name.clone(),
6380                    pending_work: Default::default(),
6381                    has_pending_diagnostic_updates: false,
6382                    progress_tokens: Default::default(),
6383                },
6384            );
6385            cx.emit(LspStoreEvent::LanguageServerAdded(
6386                server_id,
6387                LanguageServerName(server.name.into()),
6388                server.worktree_id.map(WorktreeId::from_proto),
6389            ));
6390            cx.notify();
6391        })?;
6392        Ok(())
6393    }
6394
6395    async fn handle_update_language_server(
6396        this: Entity<Self>,
6397        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
6398        mut cx: AsyncApp,
6399    ) -> Result<()> {
6400        this.update(&mut cx, |this, cx| {
6401            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
6402
6403            match envelope
6404                .payload
6405                .variant
6406                .ok_or_else(|| anyhow!("invalid variant"))?
6407            {
6408                proto::update_language_server::Variant::WorkStart(payload) => {
6409                    this.on_lsp_work_start(
6410                        language_server_id,
6411                        payload.token,
6412                        LanguageServerProgress {
6413                            title: payload.title,
6414                            is_disk_based_diagnostics_progress: false,
6415                            is_cancellable: payload.is_cancellable.unwrap_or(false),
6416                            message: payload.message,
6417                            percentage: payload.percentage.map(|p| p as usize),
6418                            last_update_at: cx.background_executor().now(),
6419                        },
6420                        cx,
6421                    );
6422                }
6423
6424                proto::update_language_server::Variant::WorkProgress(payload) => {
6425                    this.on_lsp_work_progress(
6426                        language_server_id,
6427                        payload.token,
6428                        LanguageServerProgress {
6429                            title: None,
6430                            is_disk_based_diagnostics_progress: false,
6431                            is_cancellable: payload.is_cancellable.unwrap_or(false),
6432                            message: payload.message,
6433                            percentage: payload.percentage.map(|p| p as usize),
6434                            last_update_at: cx.background_executor().now(),
6435                        },
6436                        cx,
6437                    );
6438                }
6439
6440                proto::update_language_server::Variant::WorkEnd(payload) => {
6441                    this.on_lsp_work_end(language_server_id, payload.token, cx);
6442                }
6443
6444                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
6445                    this.disk_based_diagnostics_started(language_server_id, cx);
6446                }
6447
6448                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
6449                    this.disk_based_diagnostics_finished(language_server_id, cx)
6450                }
6451            }
6452
6453            Ok(())
6454        })?
6455    }
6456
6457    async fn handle_language_server_log(
6458        this: Entity<Self>,
6459        envelope: TypedEnvelope<proto::LanguageServerLog>,
6460        mut cx: AsyncApp,
6461    ) -> Result<()> {
6462        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
6463        let log_type = envelope
6464            .payload
6465            .log_type
6466            .map(LanguageServerLogType::from_proto)
6467            .context("invalid language server log type")?;
6468
6469        let message = envelope.payload.message;
6470
6471        this.update(&mut cx, |_, cx| {
6472            cx.emit(LspStoreEvent::LanguageServerLog(
6473                language_server_id,
6474                log_type,
6475                message,
6476            ));
6477        })
6478    }
6479
6480    pub fn disk_based_diagnostics_started(
6481        &mut self,
6482        language_server_id: LanguageServerId,
6483        cx: &mut Context<Self>,
6484    ) {
6485        if let Some(language_server_status) =
6486            self.language_server_statuses.get_mut(&language_server_id)
6487        {
6488            language_server_status.has_pending_diagnostic_updates = true;
6489        }
6490
6491        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
6492        cx.emit(LspStoreEvent::LanguageServerUpdate {
6493            language_server_id,
6494            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
6495                Default::default(),
6496            ),
6497        })
6498    }
6499
6500    pub fn disk_based_diagnostics_finished(
6501        &mut self,
6502        language_server_id: LanguageServerId,
6503        cx: &mut Context<Self>,
6504    ) {
6505        if let Some(language_server_status) =
6506            self.language_server_statuses.get_mut(&language_server_id)
6507        {
6508            language_server_status.has_pending_diagnostic_updates = false;
6509        }
6510
6511        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
6512        cx.emit(LspStoreEvent::LanguageServerUpdate {
6513            language_server_id,
6514            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
6515                Default::default(),
6516            ),
6517        })
6518    }
6519
6520    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
6521    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
6522    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
6523    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
6524    // the language server might take some time to publish diagnostics.
6525    fn simulate_disk_based_diagnostics_events_if_needed(
6526        &mut self,
6527        language_server_id: LanguageServerId,
6528        cx: &mut Context<Self>,
6529    ) {
6530        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
6531
6532        let Some(LanguageServerState::Running {
6533            simulate_disk_based_diagnostics_completion,
6534            adapter,
6535            ..
6536        }) = self
6537            .as_local_mut()
6538            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
6539        else {
6540            return;
6541        };
6542
6543        if adapter.disk_based_diagnostics_progress_token.is_some() {
6544            return;
6545        }
6546
6547        let prev_task = simulate_disk_based_diagnostics_completion.replace(cx.spawn(
6548            move |this, mut cx| async move {
6549                cx.background_executor()
6550                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
6551                    .await;
6552
6553                this.update(&mut cx, |this, cx| {
6554                    this.disk_based_diagnostics_finished(language_server_id, cx);
6555
6556                    if let Some(LanguageServerState::Running {
6557                        simulate_disk_based_diagnostics_completion,
6558                        ..
6559                    }) = this.as_local_mut().and_then(|local_store| {
6560                        local_store.language_servers.get_mut(&language_server_id)
6561                    }) {
6562                        *simulate_disk_based_diagnostics_completion = None;
6563                    }
6564                })
6565                .ok();
6566            },
6567        ));
6568
6569        if prev_task.is_none() {
6570            self.disk_based_diagnostics_started(language_server_id, cx);
6571        }
6572    }
6573
6574    pub fn language_server_statuses(
6575        &self,
6576    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
6577        self.language_server_statuses
6578            .iter()
6579            .map(|(key, value)| (*key, value))
6580    }
6581
6582    pub(super) fn did_rename_entry(
6583        &self,
6584        worktree_id: WorktreeId,
6585        old_path: &Path,
6586        new_path: &Path,
6587        is_dir: bool,
6588    ) {
6589        maybe!({
6590            let local_store = self.as_local()?;
6591
6592            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
6593            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
6594
6595            for language_server in local_store.language_servers_for_worktree(worktree_id) {
6596                let Some(filter) = local_store
6597                    .language_server_paths_watched_for_rename
6598                    .get(&language_server.server_id())
6599                else {
6600                    continue;
6601                };
6602
6603                if filter.should_send_did_rename(&old_uri, is_dir) {
6604                    language_server
6605                        .notify::<DidRenameFiles>(&RenameFilesParams {
6606                            files: vec![FileRename {
6607                                old_uri: old_uri.clone(),
6608                                new_uri: new_uri.clone(),
6609                            }],
6610                        })
6611                        .log_err();
6612                }
6613            }
6614            Some(())
6615        });
6616    }
6617
6618    pub(super) fn will_rename_entry(
6619        this: WeakEntity<Self>,
6620        worktree_id: WorktreeId,
6621        old_path: &Path,
6622        new_path: &Path,
6623        is_dir: bool,
6624        cx: AsyncApp,
6625    ) -> Task<()> {
6626        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
6627        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
6628        cx.spawn(move |mut cx| async move {
6629            let mut tasks = vec![];
6630            this.update(&mut cx, |this, cx| {
6631                let local_store = this.as_local()?;
6632                let old_uri = old_uri?;
6633                let new_uri = new_uri?;
6634                for language_server in local_store.language_servers_for_worktree(worktree_id) {
6635                    let Some(filter) = local_store
6636                        .language_server_paths_watched_for_rename
6637                        .get(&language_server.server_id())
6638                    else {
6639                        continue;
6640                    };
6641                    let Some(adapter) =
6642                        this.language_server_adapter_for_id(language_server.server_id())
6643                    else {
6644                        continue;
6645                    };
6646                    if filter.should_send_will_rename(&old_uri, is_dir) {
6647                        let apply_edit = cx.spawn({
6648                            let old_uri = old_uri.clone();
6649                            let new_uri = new_uri.clone();
6650                            let language_server = language_server.clone();
6651                            |this, mut cx| async move {
6652                                let edit = language_server
6653                                    .request::<WillRenameFiles>(RenameFilesParams {
6654                                        files: vec![FileRename { old_uri, new_uri }],
6655                                    })
6656                                    .log_err()
6657                                    .await
6658                                    .flatten()?;
6659
6660                                LocalLspStore::deserialize_workspace_edit(
6661                                    this.upgrade()?,
6662                                    edit,
6663                                    false,
6664                                    adapter.clone(),
6665                                    language_server.clone(),
6666                                    &mut cx,
6667                                )
6668                                .await
6669                                .ok();
6670                                Some(())
6671                            }
6672                        });
6673                        tasks.push(apply_edit);
6674                    }
6675                }
6676                Some(())
6677            })
6678            .ok()
6679            .flatten();
6680            for task in tasks {
6681                // Await on tasks sequentially so that the order of application of edits is deterministic
6682                // (at least with regards to the order of registration of language servers)
6683                task.await;
6684            }
6685        })
6686    }
6687
6688    fn lsp_notify_abs_paths_changed(
6689        &mut self,
6690        server_id: LanguageServerId,
6691        changes: Vec<PathEvent>,
6692    ) {
6693        maybe!({
6694            let server = self.language_server_for_id(server_id)?;
6695            let changes = changes
6696                .into_iter()
6697                .filter_map(|event| {
6698                    let typ = match event.kind? {
6699                        PathEventKind::Created => lsp::FileChangeType::CREATED,
6700                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
6701                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
6702                    };
6703                    Some(lsp::FileEvent {
6704                        uri: lsp::Url::from_file_path(&event.path).ok()?,
6705                        typ,
6706                    })
6707                })
6708                .collect::<Vec<_>>();
6709            if !changes.is_empty() {
6710                server
6711                    .notify::<lsp::notification::DidChangeWatchedFiles>(
6712                        &lsp::DidChangeWatchedFilesParams { changes },
6713                    )
6714                    .log_err();
6715            }
6716            Some(())
6717        });
6718    }
6719
6720    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
6721        let local_lsp_store = self.as_local()?;
6722        if let Some(LanguageServerState::Running { server, .. }) =
6723            local_lsp_store.language_servers.get(&id)
6724        {
6725            Some(server.clone())
6726        } else if let Some((_, server)) = local_lsp_store.supplementary_language_servers.get(&id) {
6727            Some(Arc::clone(server))
6728        } else {
6729            None
6730        }
6731    }
6732
6733    fn on_lsp_progress(
6734        &mut self,
6735        progress: lsp::ProgressParams,
6736        language_server_id: LanguageServerId,
6737        disk_based_diagnostics_progress_token: Option<String>,
6738        cx: &mut Context<Self>,
6739    ) {
6740        let token = match progress.token {
6741            lsp::NumberOrString::String(token) => token,
6742            lsp::NumberOrString::Number(token) => {
6743                log::info!("skipping numeric progress token {}", token);
6744                return;
6745            }
6746        };
6747
6748        let lsp::ProgressParamsValue::WorkDone(progress) = progress.value;
6749        let language_server_status =
6750            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6751                status
6752            } else {
6753                return;
6754            };
6755
6756        if !language_server_status.progress_tokens.contains(&token) {
6757            return;
6758        }
6759
6760        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
6761            .as_ref()
6762            .map_or(false, |disk_based_token| {
6763                token.starts_with(disk_based_token)
6764            });
6765
6766        match progress {
6767            lsp::WorkDoneProgress::Begin(report) => {
6768                if is_disk_based_diagnostics_progress {
6769                    self.disk_based_diagnostics_started(language_server_id, cx);
6770                }
6771                self.on_lsp_work_start(
6772                    language_server_id,
6773                    token.clone(),
6774                    LanguageServerProgress {
6775                        title: Some(report.title),
6776                        is_disk_based_diagnostics_progress,
6777                        is_cancellable: report.cancellable.unwrap_or(false),
6778                        message: report.message.clone(),
6779                        percentage: report.percentage.map(|p| p as usize),
6780                        last_update_at: cx.background_executor().now(),
6781                    },
6782                    cx,
6783                );
6784            }
6785            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
6786                language_server_id,
6787                token,
6788                LanguageServerProgress {
6789                    title: None,
6790                    is_disk_based_diagnostics_progress,
6791                    is_cancellable: report.cancellable.unwrap_or(false),
6792                    message: report.message,
6793                    percentage: report.percentage.map(|p| p as usize),
6794                    last_update_at: cx.background_executor().now(),
6795                },
6796                cx,
6797            ),
6798            lsp::WorkDoneProgress::End(_) => {
6799                language_server_status.progress_tokens.remove(&token);
6800                self.on_lsp_work_end(language_server_id, token.clone(), cx);
6801                if is_disk_based_diagnostics_progress {
6802                    self.disk_based_diagnostics_finished(language_server_id, cx);
6803                }
6804            }
6805        }
6806    }
6807
6808    fn on_lsp_work_start(
6809        &mut self,
6810        language_server_id: LanguageServerId,
6811        token: String,
6812        progress: LanguageServerProgress,
6813        cx: &mut Context<Self>,
6814    ) {
6815        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6816            status.pending_work.insert(token.clone(), progress.clone());
6817            cx.notify();
6818        }
6819        cx.emit(LspStoreEvent::LanguageServerUpdate {
6820            language_server_id,
6821            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
6822                token,
6823                title: progress.title,
6824                message: progress.message,
6825                percentage: progress.percentage.map(|p| p as u32),
6826                is_cancellable: Some(progress.is_cancellable),
6827            }),
6828        })
6829    }
6830
6831    fn on_lsp_work_progress(
6832        &mut self,
6833        language_server_id: LanguageServerId,
6834        token: String,
6835        progress: LanguageServerProgress,
6836        cx: &mut Context<Self>,
6837    ) {
6838        let mut did_update = false;
6839        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6840            match status.pending_work.entry(token.clone()) {
6841                btree_map::Entry::Vacant(entry) => {
6842                    entry.insert(progress.clone());
6843                    did_update = true;
6844                }
6845                btree_map::Entry::Occupied(mut entry) => {
6846                    let entry = entry.get_mut();
6847                    if (progress.last_update_at - entry.last_update_at)
6848                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
6849                    {
6850                        entry.last_update_at = progress.last_update_at;
6851                        if progress.message.is_some() {
6852                            entry.message = progress.message.clone();
6853                        }
6854                        if progress.percentage.is_some() {
6855                            entry.percentage = progress.percentage;
6856                        }
6857                        if progress.is_cancellable != entry.is_cancellable {
6858                            entry.is_cancellable = progress.is_cancellable;
6859                        }
6860                        did_update = true;
6861                    }
6862                }
6863            }
6864        }
6865
6866        if did_update {
6867            cx.emit(LspStoreEvent::LanguageServerUpdate {
6868                language_server_id,
6869                message: proto::update_language_server::Variant::WorkProgress(
6870                    proto::LspWorkProgress {
6871                        token,
6872                        message: progress.message,
6873                        percentage: progress.percentage.map(|p| p as u32),
6874                        is_cancellable: Some(progress.is_cancellable),
6875                    },
6876                ),
6877            })
6878        }
6879    }
6880
6881    fn on_lsp_work_end(
6882        &mut self,
6883        language_server_id: LanguageServerId,
6884        token: String,
6885        cx: &mut Context<Self>,
6886    ) {
6887        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
6888            if let Some(work) = status.pending_work.remove(&token) {
6889                if !work.is_disk_based_diagnostics_progress {
6890                    cx.emit(LspStoreEvent::RefreshInlayHints);
6891                }
6892            }
6893            cx.notify();
6894        }
6895
6896        cx.emit(LspStoreEvent::LanguageServerUpdate {
6897            language_server_id,
6898            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
6899        })
6900    }
6901
6902    pub async fn handle_resolve_completion_documentation(
6903        this: Entity<Self>,
6904        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
6905        mut cx: AsyncApp,
6906    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
6907        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
6908
6909        let completion = this
6910            .read_with(&cx, |this, cx| {
6911                let id = LanguageServerId(envelope.payload.language_server_id as usize);
6912                let Some(server) = this.language_server_for_id(id) else {
6913                    return Err(anyhow!("No language server {id}"));
6914                };
6915
6916                Ok(cx.background_spawn(async move {
6917                    let can_resolve = server
6918                        .capabilities()
6919                        .completion_provider
6920                        .as_ref()
6921                        .and_then(|options| options.resolve_provider)
6922                        .unwrap_or(false);
6923                    if can_resolve {
6924                        server
6925                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
6926                            .await
6927                    } else {
6928                        anyhow::Ok(lsp_completion)
6929                    }
6930                }))
6931            })??
6932            .await?;
6933
6934        let mut documentation_is_markdown = false;
6935        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
6936        let documentation = match completion.documentation {
6937            Some(lsp::Documentation::String(text)) => text,
6938
6939            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
6940                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
6941                value
6942            }
6943
6944            _ => String::new(),
6945        };
6946
6947        // If we have a new buffer_id, that means we're talking to a new client
6948        // and want to check for new text_edits in the completion too.
6949        let mut old_start = None;
6950        let mut old_end = None;
6951        let mut new_text = String::default();
6952        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
6953            let buffer_snapshot = this.update(&mut cx, |this, cx| {
6954                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6955                anyhow::Ok(buffer.read(cx).snapshot())
6956            })??;
6957
6958            if let Some(text_edit) = completion.text_edit.as_ref() {
6959                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
6960
6961                if let Some((old_range, mut text_edit_new_text)) = edit {
6962                    LineEnding::normalize(&mut text_edit_new_text);
6963
6964                    new_text = text_edit_new_text;
6965                    old_start = Some(serialize_anchor(&old_range.start));
6966                    old_end = Some(serialize_anchor(&old_range.end));
6967                }
6968            }
6969        }
6970
6971        Ok(proto::ResolveCompletionDocumentationResponse {
6972            documentation,
6973            documentation_is_markdown,
6974            old_start,
6975            old_end,
6976            new_text,
6977            lsp_completion,
6978        })
6979    }
6980
6981    async fn handle_on_type_formatting(
6982        this: Entity<Self>,
6983        envelope: TypedEnvelope<proto::OnTypeFormatting>,
6984        mut cx: AsyncApp,
6985    ) -> Result<proto::OnTypeFormattingResponse> {
6986        let on_type_formatting = this.update(&mut cx, |this, cx| {
6987            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6988            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6989            let position = envelope
6990                .payload
6991                .position
6992                .and_then(deserialize_anchor)
6993                .ok_or_else(|| anyhow!("invalid position"))?;
6994            Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
6995                buffer,
6996                position,
6997                envelope.payload.trigger.clone(),
6998                cx,
6999            ))
7000        })??;
7001
7002        let transaction = on_type_formatting
7003            .await?
7004            .as_ref()
7005            .map(language::proto::serialize_transaction);
7006        Ok(proto::OnTypeFormattingResponse { transaction })
7007    }
7008
7009    async fn handle_refresh_inlay_hints(
7010        this: Entity<Self>,
7011        _: TypedEnvelope<proto::RefreshInlayHints>,
7012        mut cx: AsyncApp,
7013    ) -> Result<proto::Ack> {
7014        this.update(&mut cx, |_, cx| {
7015            cx.emit(LspStoreEvent::RefreshInlayHints);
7016        })?;
7017        Ok(proto::Ack {})
7018    }
7019
7020    async fn handle_inlay_hints(
7021        this: Entity<Self>,
7022        envelope: TypedEnvelope<proto::InlayHints>,
7023        mut cx: AsyncApp,
7024    ) -> Result<proto::InlayHintsResponse> {
7025        let sender_id = envelope.original_sender_id().unwrap_or_default();
7026        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7027        let buffer = this.update(&mut cx, |this, cx| {
7028            this.buffer_store.read(cx).get_existing(buffer_id)
7029        })??;
7030        buffer
7031            .update(&mut cx, |buffer, _| {
7032                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
7033            })?
7034            .await
7035            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
7036
7037        let start = envelope
7038            .payload
7039            .start
7040            .and_then(deserialize_anchor)
7041            .context("missing range start")?;
7042        let end = envelope
7043            .payload
7044            .end
7045            .and_then(deserialize_anchor)
7046            .context("missing range end")?;
7047        let buffer_hints = this
7048            .update(&mut cx, |lsp_store, cx| {
7049                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
7050            })?
7051            .await
7052            .context("inlay hints fetch")?;
7053
7054        this.update(&mut cx, |project, cx| {
7055            InlayHints::response_to_proto(
7056                buffer_hints,
7057                project,
7058                sender_id,
7059                &buffer.read(cx).version(),
7060                cx,
7061            )
7062        })
7063    }
7064
7065    async fn handle_resolve_inlay_hint(
7066        this: Entity<Self>,
7067        envelope: TypedEnvelope<proto::ResolveInlayHint>,
7068        mut cx: AsyncApp,
7069    ) -> Result<proto::ResolveInlayHintResponse> {
7070        let proto_hint = envelope
7071            .payload
7072            .hint
7073            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
7074        let hint = InlayHints::proto_to_project_hint(proto_hint)
7075            .context("resolved proto inlay hint conversion")?;
7076        let buffer = this.update(&mut cx, |this, cx| {
7077            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7078            this.buffer_store.read(cx).get_existing(buffer_id)
7079        })??;
7080        let response_hint = this
7081            .update(&mut cx, |this, cx| {
7082                this.resolve_inlay_hint(
7083                    hint,
7084                    buffer,
7085                    LanguageServerId(envelope.payload.language_server_id as usize),
7086                    cx,
7087                )
7088            })?
7089            .await
7090            .context("inlay hints fetch")?;
7091        Ok(proto::ResolveInlayHintResponse {
7092            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
7093        })
7094    }
7095
7096    async fn handle_open_buffer_for_symbol(
7097        this: Entity<Self>,
7098        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
7099        mut cx: AsyncApp,
7100    ) -> Result<proto::OpenBufferForSymbolResponse> {
7101        let peer_id = envelope.original_sender_id().unwrap_or_default();
7102        let symbol = envelope
7103            .payload
7104            .symbol
7105            .ok_or_else(|| anyhow!("invalid symbol"))?;
7106        let symbol = Self::deserialize_symbol(symbol)?;
7107        let symbol = this.update(&mut cx, |this, _| {
7108            let signature = this.symbol_signature(&symbol.path);
7109            if signature == symbol.signature {
7110                Ok(symbol)
7111            } else {
7112                Err(anyhow!("invalid symbol signature"))
7113            }
7114        })??;
7115        let buffer = this
7116            .update(&mut cx, |this, cx| {
7117                this.open_buffer_for_symbol(
7118                    &Symbol {
7119                        language_server_name: symbol.language_server_name,
7120                        source_worktree_id: symbol.source_worktree_id,
7121                        source_language_server_id: symbol.source_language_server_id,
7122                        path: symbol.path,
7123                        name: symbol.name,
7124                        kind: symbol.kind,
7125                        range: symbol.range,
7126                        signature: symbol.signature,
7127                        label: CodeLabel {
7128                            text: Default::default(),
7129                            runs: Default::default(),
7130                            filter_range: Default::default(),
7131                        },
7132                    },
7133                    cx,
7134                )
7135            })?
7136            .await?;
7137
7138        this.update(&mut cx, |this, cx| {
7139            let is_private = buffer
7140                .read(cx)
7141                .file()
7142                .map(|f| f.is_private())
7143                .unwrap_or_default();
7144            if is_private {
7145                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
7146            } else {
7147                this.buffer_store
7148                    .update(cx, |buffer_store, cx| {
7149                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
7150                    })
7151                    .detach_and_log_err(cx);
7152                let buffer_id = buffer.read(cx).remote_id().to_proto();
7153                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
7154            }
7155        })?
7156    }
7157
7158    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
7159        let mut hasher = Sha256::new();
7160        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
7161        hasher.update(project_path.path.to_string_lossy().as_bytes());
7162        hasher.update(self.nonce.to_be_bytes());
7163        hasher.finalize().as_slice().try_into().unwrap()
7164    }
7165
7166    pub async fn handle_get_project_symbols(
7167        this: Entity<Self>,
7168        envelope: TypedEnvelope<proto::GetProjectSymbols>,
7169        mut cx: AsyncApp,
7170    ) -> Result<proto::GetProjectSymbolsResponse> {
7171        let symbols = this
7172            .update(&mut cx, |this, cx| {
7173                this.symbols(&envelope.payload.query, cx)
7174            })?
7175            .await?;
7176
7177        Ok(proto::GetProjectSymbolsResponse {
7178            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
7179        })
7180    }
7181
7182    pub async fn handle_restart_language_servers(
7183        this: Entity<Self>,
7184        envelope: TypedEnvelope<proto::RestartLanguageServers>,
7185        mut cx: AsyncApp,
7186    ) -> Result<proto::Ack> {
7187        this.update(&mut cx, |this, cx| {
7188            let buffers = this.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
7189            this.restart_language_servers_for_buffers(buffers, cx);
7190        })?;
7191
7192        Ok(proto::Ack {})
7193    }
7194
7195    pub async fn handle_cancel_language_server_work(
7196        this: Entity<Self>,
7197        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
7198        mut cx: AsyncApp,
7199    ) -> Result<proto::Ack> {
7200        this.update(&mut cx, |this, cx| {
7201            if let Some(work) = envelope.payload.work {
7202                match work {
7203                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
7204                        let buffers =
7205                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
7206                        this.cancel_language_server_work_for_buffers(buffers, cx);
7207                    }
7208                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
7209                        let server_id = LanguageServerId::from_proto(work.language_server_id);
7210                        this.cancel_language_server_work(server_id, work.token, cx);
7211                    }
7212                }
7213            }
7214        })?;
7215
7216        Ok(proto::Ack {})
7217    }
7218
7219    fn buffer_ids_to_buffers(
7220        &mut self,
7221        buffer_ids: impl Iterator<Item = u64>,
7222        cx: &mut Context<Self>,
7223    ) -> Vec<Entity<Buffer>> {
7224        buffer_ids
7225            .into_iter()
7226            .flat_map(|buffer_id| {
7227                self.buffer_store
7228                    .read(cx)
7229                    .get(BufferId::new(buffer_id).log_err()?)
7230            })
7231            .collect::<Vec<_>>()
7232    }
7233
7234    async fn handle_apply_additional_edits_for_completion(
7235        this: Entity<Self>,
7236        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
7237        mut cx: AsyncApp,
7238    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
7239        let (buffer, completion) = this.update(&mut cx, |this, cx| {
7240            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7241            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
7242            let completion = Self::deserialize_completion(
7243                envelope
7244                    .payload
7245                    .completion
7246                    .ok_or_else(|| anyhow!("invalid completion"))?,
7247            )?;
7248            anyhow::Ok((buffer, completion))
7249        })??;
7250
7251        let apply_additional_edits = this.update(&mut cx, |this, cx| {
7252            this.apply_additional_edits_for_completion(
7253                buffer,
7254                Rc::new(RefCell::new(Box::new([Completion {
7255                    old_range: completion.old_range,
7256                    new_text: completion.new_text,
7257                    source: completion.source,
7258                    documentation: None,
7259                    label: CodeLabel {
7260                        text: Default::default(),
7261                        runs: Default::default(),
7262                        filter_range: Default::default(),
7263                    },
7264                    confirm: None,
7265                }]))),
7266                0,
7267                false,
7268                cx,
7269            )
7270        })?;
7271
7272        Ok(proto::ApplyCompletionAdditionalEditsResponse {
7273            transaction: apply_additional_edits
7274                .await?
7275                .as_ref()
7276                .map(language::proto::serialize_transaction),
7277        })
7278    }
7279
7280    pub fn last_formatting_failure(&self) -> Option<&str> {
7281        self.last_formatting_failure.as_deref()
7282    }
7283
7284    pub fn reset_last_formatting_failure(&mut self) {
7285        self.last_formatting_failure = None;
7286    }
7287
7288    pub fn environment_for_buffer(
7289        &self,
7290        buffer: &Entity<Buffer>,
7291        cx: &mut Context<Self>,
7292    ) -> Shared<Task<Option<HashMap<String, String>>>> {
7293        let worktree_id = buffer.read(cx).file().map(|file| file.worktree_id(cx));
7294        let worktree_abs_path = worktree_id.and_then(|worktree_id| {
7295            self.worktree_store
7296                .read(cx)
7297                .worktree_for_id(worktree_id, cx)
7298                .map(|entry| entry.read(cx).abs_path().clone())
7299        });
7300
7301        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
7302            environment.update(cx, |env, cx| {
7303                env.get_environment(worktree_id, worktree_abs_path, cx)
7304            })
7305        } else {
7306            Task::ready(None).shared()
7307        }
7308    }
7309
7310    pub fn format(
7311        &mut self,
7312        buffers: HashSet<Entity<Buffer>>,
7313        target: LspFormatTarget,
7314        push_to_history: bool,
7315        trigger: FormatTrigger,
7316        cx: &mut Context<Self>,
7317    ) -> Task<anyhow::Result<ProjectTransaction>> {
7318        if let Some(_) = self.as_local() {
7319            let buffers = buffers
7320                .into_iter()
7321                .map(|buffer_handle| {
7322                    let buffer = buffer_handle.read(cx);
7323                    let buffer_abs_path = File::from_dyn(buffer.file())
7324                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
7325
7326                    (buffer_handle, buffer_abs_path, buffer.remote_id())
7327                })
7328                .collect::<Vec<_>>();
7329
7330            cx.spawn(move |lsp_store, mut cx| async move {
7331                let mut formattable_buffers = Vec::with_capacity(buffers.len());
7332
7333                for (handle, abs_path, id) in buffers {
7334                    let env = lsp_store
7335                        .update(&mut cx, |lsp_store, cx| {
7336                            lsp_store.environment_for_buffer(&handle, cx)
7337                        })?
7338                        .await;
7339
7340                    let ranges = match &target {
7341                        LspFormatTarget::Buffers => None,
7342                        LspFormatTarget::Ranges(ranges) => {
7343                            let Some(ranges) = ranges.get(&id) else {
7344                                return Err(anyhow!("No format ranges provided for buffer"));
7345                            };
7346                            Some(ranges.clone())
7347                        }
7348                    };
7349
7350                    formattable_buffers.push(FormattableBuffer {
7351                        handle,
7352                        abs_path,
7353                        env,
7354                        ranges,
7355                    });
7356                }
7357
7358                let result = LocalLspStore::format_locally(
7359                    lsp_store.clone(),
7360                    formattable_buffers,
7361                    push_to_history,
7362                    trigger,
7363                    cx.clone(),
7364                )
7365                .await;
7366                lsp_store.update(&mut cx, |lsp_store, _| {
7367                    lsp_store.update_last_formatting_failure(&result);
7368                })?;
7369
7370                result
7371            })
7372        } else if let Some((client, project_id)) = self.upstream_client() {
7373            // Don't support formatting ranges via remote
7374            match target {
7375                LspFormatTarget::Buffers => {}
7376                LspFormatTarget::Ranges(_) => {
7377                    return Task::ready(Ok(ProjectTransaction::default()));
7378                }
7379            }
7380
7381            let buffer_store = self.buffer_store();
7382            cx.spawn(move |lsp_store, mut cx| async move {
7383                let result = client
7384                    .request(proto::FormatBuffers {
7385                        project_id,
7386                        trigger: trigger as i32,
7387                        buffer_ids: buffers
7388                            .iter()
7389                            .map(|buffer| {
7390                                buffer.update(&mut cx, |buffer, _| buffer.remote_id().into())
7391                            })
7392                            .collect::<Result<_>>()?,
7393                    })
7394                    .await
7395                    .and_then(|result| result.transaction.context("missing transaction"));
7396
7397                lsp_store.update(&mut cx, |lsp_store, _| {
7398                    lsp_store.update_last_formatting_failure(&result);
7399                })?;
7400
7401                let transaction_response = result?;
7402                buffer_store
7403                    .update(&mut cx, |buffer_store, cx| {
7404                        buffer_store.deserialize_project_transaction(
7405                            transaction_response,
7406                            push_to_history,
7407                            cx,
7408                        )
7409                    })?
7410                    .await
7411            })
7412        } else {
7413            Task::ready(Ok(ProjectTransaction::default()))
7414        }
7415    }
7416
7417    async fn handle_format_buffers(
7418        this: Entity<Self>,
7419        envelope: TypedEnvelope<proto::FormatBuffers>,
7420        mut cx: AsyncApp,
7421    ) -> Result<proto::FormatBuffersResponse> {
7422        let sender_id = envelope.original_sender_id().unwrap_or_default();
7423        let format = this.update(&mut cx, |this, cx| {
7424            let mut buffers = HashSet::default();
7425            for buffer_id in &envelope.payload.buffer_ids {
7426                let buffer_id = BufferId::new(*buffer_id)?;
7427                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
7428            }
7429            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
7430            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
7431        })??;
7432
7433        let project_transaction = format.await?;
7434        let project_transaction = this.update(&mut cx, |this, cx| {
7435            this.buffer_store.update(cx, |buffer_store, cx| {
7436                buffer_store.serialize_project_transaction_for_peer(
7437                    project_transaction,
7438                    sender_id,
7439                    cx,
7440                )
7441            })
7442        })?;
7443        Ok(proto::FormatBuffersResponse {
7444            transaction: Some(project_transaction),
7445        })
7446    }
7447
7448    async fn handle_apply_code_action_kind(
7449        this: Entity<Self>,
7450        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
7451        mut cx: AsyncApp,
7452    ) -> Result<proto::ApplyCodeActionKindResponse> {
7453        let sender_id = envelope.original_sender_id().unwrap_or_default();
7454        let format = this.update(&mut cx, |this, cx| {
7455            let mut buffers = HashSet::default();
7456            for buffer_id in &envelope.payload.buffer_ids {
7457                let buffer_id = BufferId::new(*buffer_id)?;
7458                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
7459            }
7460            let kind = match envelope.payload.kind.as_str() {
7461                "" => Ok(CodeActionKind::EMPTY),
7462                "quickfix" => Ok(CodeActionKind::QUICKFIX),
7463                "refactor" => Ok(CodeActionKind::REFACTOR),
7464                "refactor.extract" => Ok(CodeActionKind::REFACTOR_EXTRACT),
7465                "refactor.inline" => Ok(CodeActionKind::REFACTOR_INLINE),
7466                "refactor.rewrite" => Ok(CodeActionKind::REFACTOR_REWRITE),
7467                "source" => Ok(CodeActionKind::SOURCE),
7468                "source.organizeImports" => Ok(CodeActionKind::SOURCE_ORGANIZE_IMPORTS),
7469                "source.fixAll" => Ok(CodeActionKind::SOURCE_FIX_ALL),
7470                _ => Err(anyhow!("Invalid code action kind")),
7471            }?;
7472            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
7473        })??;
7474
7475        let project_transaction = format.await?;
7476        let project_transaction = this.update(&mut cx, |this, cx| {
7477            this.buffer_store.update(cx, |buffer_store, cx| {
7478                buffer_store.serialize_project_transaction_for_peer(
7479                    project_transaction,
7480                    sender_id,
7481                    cx,
7482                )
7483            })
7484        })?;
7485        Ok(proto::ApplyCodeActionKindResponse {
7486            transaction: Some(project_transaction),
7487        })
7488    }
7489
7490    async fn shutdown_language_server(
7491        server_state: Option<LanguageServerState>,
7492        name: LanguageServerName,
7493        cx: AsyncApp,
7494    ) {
7495        let server = match server_state {
7496            Some(LanguageServerState::Starting { startup, .. }) => {
7497                let mut timer = cx
7498                    .background_executor()
7499                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
7500                    .fuse();
7501
7502                select! {
7503                    server = startup.fuse() => server,
7504                    _ = timer => {
7505                        log::info!(
7506                            "timeout waiting for language server {} to finish launching before stopping",
7507                            name
7508                        );
7509                        None
7510                    },
7511                }
7512            }
7513
7514            Some(LanguageServerState::Running { server, .. }) => Some(server),
7515
7516            None => None,
7517        };
7518
7519        if let Some(server) = server {
7520            if let Some(shutdown) = server.shutdown() {
7521                shutdown.await;
7522            }
7523        }
7524    }
7525
7526    // Returns a list of all of the worktrees which no longer have a language server and the root path
7527    // for the stopped server
7528    fn stop_local_language_server(
7529        &mut self,
7530        server_id: LanguageServerId,
7531        name: LanguageServerName,
7532        cx: &mut Context<Self>,
7533    ) -> Task<Vec<WorktreeId>> {
7534        let local = match &mut self.mode {
7535            LspStoreMode::Local(local) => local,
7536            _ => {
7537                return Task::ready(Vec::new());
7538            }
7539        };
7540
7541        let mut orphaned_worktrees = vec![];
7542        // Remove this server ID from all entries in the given worktree.
7543        local.language_server_ids.retain(|(worktree, _), ids| {
7544            if !ids.remove(&server_id) {
7545                return true;
7546            }
7547
7548            if ids.is_empty() {
7549                orphaned_worktrees.push(*worktree);
7550                false
7551            } else {
7552                true
7553            }
7554        });
7555        let _ = self.language_server_statuses.remove(&server_id);
7556        log::info!("stopping language server {name}");
7557        self.buffer_store.update(cx, |buffer_store, cx| {
7558            for buffer in buffer_store.buffers() {
7559                buffer.update(cx, |buffer, cx| {
7560                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
7561                    buffer.set_completion_triggers(server_id, Default::default(), cx);
7562                });
7563            }
7564        });
7565
7566        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
7567            summaries.retain(|path, summaries_by_server_id| {
7568                if summaries_by_server_id.remove(&server_id).is_some() {
7569                    if let Some((client, project_id)) = self.downstream_client.clone() {
7570                        client
7571                            .send(proto::UpdateDiagnosticSummary {
7572                                project_id,
7573                                worktree_id: worktree_id.to_proto(),
7574                                summary: Some(proto::DiagnosticSummary {
7575                                    path: path.as_ref().to_proto(),
7576                                    language_server_id: server_id.0 as u64,
7577                                    error_count: 0,
7578                                    warning_count: 0,
7579                                }),
7580                            })
7581                            .log_err();
7582                    }
7583                    !summaries_by_server_id.is_empty()
7584                } else {
7585                    true
7586                }
7587            });
7588        }
7589
7590        let local = self.as_local_mut().unwrap();
7591        for diagnostics in local.diagnostics.values_mut() {
7592            diagnostics.retain(|_, diagnostics_by_server_id| {
7593                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
7594                    diagnostics_by_server_id.remove(ix);
7595                    !diagnostics_by_server_id.is_empty()
7596                } else {
7597                    true
7598                }
7599            });
7600        }
7601        local.language_server_watched_paths.remove(&server_id);
7602        let server_state = local.language_servers.remove(&server_id);
7603        cx.notify();
7604        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
7605        cx.spawn(move |_, cx| async move {
7606            Self::shutdown_language_server(server_state, name, cx).await;
7607            orphaned_worktrees
7608        })
7609    }
7610
7611    pub fn restart_language_servers_for_buffers(
7612        &mut self,
7613        buffers: Vec<Entity<Buffer>>,
7614        cx: &mut Context<Self>,
7615    ) {
7616        if let Some((client, project_id)) = self.upstream_client() {
7617            let request = client.request(proto::RestartLanguageServers {
7618                project_id,
7619                buffer_ids: buffers
7620                    .into_iter()
7621                    .map(|b| b.read(cx).remote_id().to_proto())
7622                    .collect(),
7623            });
7624            cx.background_spawn(request).detach_and_log_err(cx);
7625        } else {
7626            let Some(local) = self.as_local_mut() else {
7627                return;
7628            };
7629            let language_servers_to_stop = buffers
7630                .iter()
7631                .flat_map(|buffer| {
7632                    buffer.update(cx, |buffer, cx| {
7633                        local.language_server_ids_for_buffer(buffer, cx)
7634                    })
7635                })
7636                .collect::<BTreeSet<_>>();
7637            local.lsp_tree.update(cx, |this, _| {
7638                this.remove_nodes(&language_servers_to_stop);
7639            });
7640            let tasks = language_servers_to_stop
7641                .into_iter()
7642                .map(|server| {
7643                    let name = self
7644                        .language_server_statuses
7645                        .get(&server)
7646                        .map(|state| state.name.as_str().into())
7647                        .unwrap_or_else(|| LanguageServerName::from("Unknown"));
7648                    self.stop_local_language_server(server, name, cx)
7649                })
7650                .collect::<Vec<_>>();
7651
7652            cx.spawn(|this, mut cx| async move {
7653                cx.background_spawn(futures::future::join_all(tasks)).await;
7654                this.update(&mut cx, |this, cx| {
7655                    for buffer in buffers {
7656                        this.register_buffer_with_language_servers(&buffer, true, cx);
7657                    }
7658                })
7659                .ok()
7660            })
7661            .detach();
7662        }
7663    }
7664
7665    pub fn update_diagnostics(
7666        &mut self,
7667        language_server_id: LanguageServerId,
7668        mut params: lsp::PublishDiagnosticsParams,
7669        disk_based_sources: &[String],
7670        cx: &mut Context<Self>,
7671    ) -> Result<()> {
7672        if !self.mode.is_local() {
7673            anyhow::bail!("called update_diagnostics on remote");
7674        }
7675        let abs_path = params
7676            .uri
7677            .to_file_path()
7678            .map_err(|_| anyhow!("URI is not a file"))?;
7679        let mut diagnostics = Vec::default();
7680        let mut primary_diagnostic_group_ids = HashMap::default();
7681        let mut sources_by_group_id = HashMap::default();
7682        let mut supporting_diagnostics = HashMap::default();
7683
7684        // Ensure that primary diagnostics are always the most severe
7685        params.diagnostics.sort_by_key(|item| item.severity);
7686
7687        for diagnostic in &params.diagnostics {
7688            let source = diagnostic.source.as_ref();
7689            let range = range_from_lsp(diagnostic.range);
7690            let is_supporting = diagnostic
7691                .related_information
7692                .as_ref()
7693                .map_or(false, |infos| {
7694                    infos.iter().any(|info| {
7695                        primary_diagnostic_group_ids.contains_key(&(
7696                            source,
7697                            diagnostic.code.clone(),
7698                            range_from_lsp(info.location.range),
7699                        ))
7700                    })
7701                });
7702
7703            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
7704                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
7705            });
7706
7707            if is_supporting {
7708                supporting_diagnostics.insert(
7709                    (source, diagnostic.code.clone(), range),
7710                    (diagnostic.severity, is_unnecessary),
7711                );
7712            } else {
7713                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
7714                let is_disk_based =
7715                    source.map_or(false, |source| disk_based_sources.contains(source));
7716
7717                sources_by_group_id.insert(group_id, source);
7718                primary_diagnostic_group_ids
7719                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
7720
7721                diagnostics.push(DiagnosticEntry {
7722                    range,
7723                    diagnostic: Diagnostic {
7724                        source: diagnostic.source.clone(),
7725                        code: diagnostic.code.clone(),
7726                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
7727                        message: diagnostic.message.trim().to_string(),
7728                        group_id,
7729                        is_primary: true,
7730                        is_disk_based,
7731                        is_unnecessary,
7732                        data: diagnostic.data.clone(),
7733                    },
7734                });
7735                if let Some(infos) = &diagnostic.related_information {
7736                    for info in infos {
7737                        if info.location.uri == params.uri && !info.message.is_empty() {
7738                            let range = range_from_lsp(info.location.range);
7739                            diagnostics.push(DiagnosticEntry {
7740                                range,
7741                                diagnostic: Diagnostic {
7742                                    source: diagnostic.source.clone(),
7743                                    code: diagnostic.code.clone(),
7744                                    severity: DiagnosticSeverity::INFORMATION,
7745                                    message: info.message.trim().to_string(),
7746                                    group_id,
7747                                    is_primary: false,
7748                                    is_disk_based,
7749                                    is_unnecessary: false,
7750                                    data: diagnostic.data.clone(),
7751                                },
7752                            });
7753                        }
7754                    }
7755                }
7756            }
7757        }
7758
7759        for entry in &mut diagnostics {
7760            let diagnostic = &mut entry.diagnostic;
7761            if !diagnostic.is_primary {
7762                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
7763                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
7764                    source,
7765                    diagnostic.code.clone(),
7766                    entry.range.clone(),
7767                )) {
7768                    if let Some(severity) = severity {
7769                        diagnostic.severity = severity;
7770                    }
7771                    diagnostic.is_unnecessary = is_unnecessary;
7772                }
7773            }
7774        }
7775
7776        self.update_diagnostic_entries(
7777            language_server_id,
7778            abs_path,
7779            params.version,
7780            diagnostics,
7781            cx,
7782        )?;
7783        Ok(())
7784    }
7785
7786    fn insert_newly_running_language_server(
7787        &mut self,
7788        adapter: Arc<CachedLspAdapter>,
7789        language_server: Arc<LanguageServer>,
7790        server_id: LanguageServerId,
7791        key: (WorktreeId, LanguageServerName),
7792        workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
7793        cx: &mut Context<Self>,
7794    ) {
7795        let Some(local) = self.as_local_mut() else {
7796            return;
7797        };
7798        // If the language server for this key doesn't match the server id, don't store the
7799        // server. Which will cause it to be dropped, killing the process
7800        if local
7801            .language_server_ids
7802            .get(&key)
7803            .map(|ids| !ids.contains(&server_id))
7804            .unwrap_or(false)
7805        {
7806            return;
7807        }
7808
7809        // Update language_servers collection with Running variant of LanguageServerState
7810        // indicating that the server is up and running and ready
7811        let workspace_folders = workspace_folders.lock().clone();
7812        local.language_servers.insert(
7813            server_id,
7814            LanguageServerState::running(
7815                workspace_folders,
7816                adapter.clone(),
7817                language_server.clone(),
7818                None,
7819            ),
7820        );
7821        if let Some(file_ops_caps) = language_server
7822            .capabilities()
7823            .workspace
7824            .as_ref()
7825            .and_then(|ws| ws.file_operations.as_ref())
7826        {
7827            let did_rename_caps = file_ops_caps.did_rename.as_ref();
7828            let will_rename_caps = file_ops_caps.will_rename.as_ref();
7829            if did_rename_caps.or(will_rename_caps).is_some() {
7830                let watcher = RenamePathsWatchedForServer::default()
7831                    .with_did_rename_patterns(did_rename_caps)
7832                    .with_will_rename_patterns(will_rename_caps);
7833                local
7834                    .language_server_paths_watched_for_rename
7835                    .insert(server_id, watcher);
7836            }
7837        }
7838
7839        self.language_server_statuses.insert(
7840            server_id,
7841            LanguageServerStatus {
7842                name: language_server.name().to_string(),
7843                pending_work: Default::default(),
7844                has_pending_diagnostic_updates: false,
7845                progress_tokens: Default::default(),
7846            },
7847        );
7848
7849        cx.emit(LspStoreEvent::LanguageServerAdded(
7850            server_id,
7851            language_server.name(),
7852            Some(key.0),
7853        ));
7854        cx.emit(LspStoreEvent::RefreshInlayHints);
7855
7856        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
7857            downstream_client
7858                .send(proto::StartLanguageServer {
7859                    project_id: *project_id,
7860                    server: Some(proto::LanguageServer {
7861                        id: server_id.0 as u64,
7862                        name: language_server.name().to_string(),
7863                        worktree_id: Some(key.0.to_proto()),
7864                    }),
7865                })
7866                .log_err();
7867        }
7868
7869        // Tell the language server about every open buffer in the worktree that matches the language.
7870        self.buffer_store.clone().update(cx, |buffer_store, cx| {
7871            for buffer_handle in buffer_store.buffers() {
7872                let buffer = buffer_handle.read(cx);
7873                let file = match File::from_dyn(buffer.file()) {
7874                    Some(file) => file,
7875                    None => continue,
7876                };
7877                let language = match buffer.language() {
7878                    Some(language) => language,
7879                    None => continue,
7880                };
7881
7882                if file.worktree.read(cx).id() != key.0
7883                    || !self
7884                        .languages
7885                        .lsp_adapters(&language.name())
7886                        .iter()
7887                        .any(|a| a.name == key.1)
7888                {
7889                    continue;
7890                }
7891                // didOpen
7892                let file = match file.as_local() {
7893                    Some(file) => file,
7894                    None => continue,
7895                };
7896
7897                let local = self.as_local_mut().unwrap();
7898
7899                if local.registered_buffers.contains_key(&buffer.remote_id()) {
7900                    let versions = local
7901                        .buffer_snapshots
7902                        .entry(buffer.remote_id())
7903                        .or_default()
7904                        .entry(server_id)
7905                        .and_modify(|_| {
7906                            assert!(
7907                            false,
7908                            "There should not be an existing snapshot for a newly inserted buffer"
7909                        )
7910                        })
7911                        .or_insert_with(|| {
7912                            vec![LspBufferSnapshot {
7913                                version: 0,
7914                                snapshot: buffer.text_snapshot(),
7915                            }]
7916                        });
7917
7918                    let snapshot = versions.last().unwrap();
7919                    let version = snapshot.version;
7920                    let initial_snapshot = &snapshot.snapshot;
7921                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
7922                    language_server.register_buffer(
7923                        uri,
7924                        adapter.language_id(&language.name()),
7925                        version,
7926                        initial_snapshot.text(),
7927                    );
7928                }
7929                buffer_handle.update(cx, |buffer, cx| {
7930                    buffer.set_completion_triggers(
7931                        server_id,
7932                        language_server
7933                            .capabilities()
7934                            .completion_provider
7935                            .as_ref()
7936                            .and_then(|provider| {
7937                                provider
7938                                    .trigger_characters
7939                                    .as_ref()
7940                                    .map(|characters| characters.iter().cloned().collect())
7941                            })
7942                            .unwrap_or_default(),
7943                        cx,
7944                    )
7945                });
7946            }
7947        });
7948
7949        cx.notify();
7950    }
7951
7952    pub fn language_servers_running_disk_based_diagnostics(
7953        &self,
7954    ) -> impl Iterator<Item = LanguageServerId> + '_ {
7955        self.language_server_statuses
7956            .iter()
7957            .filter_map(|(id, status)| {
7958                if status.has_pending_diagnostic_updates {
7959                    Some(*id)
7960                } else {
7961                    None
7962                }
7963            })
7964    }
7965
7966    pub(crate) fn cancel_language_server_work_for_buffers(
7967        &mut self,
7968        buffers: impl IntoIterator<Item = Entity<Buffer>>,
7969        cx: &mut Context<Self>,
7970    ) {
7971        if let Some((client, project_id)) = self.upstream_client() {
7972            let request = client.request(proto::CancelLanguageServerWork {
7973                project_id,
7974                work: Some(proto::cancel_language_server_work::Work::Buffers(
7975                    proto::cancel_language_server_work::Buffers {
7976                        buffer_ids: buffers
7977                            .into_iter()
7978                            .map(|b| b.read(cx).remote_id().to_proto())
7979                            .collect(),
7980                    },
7981                )),
7982            });
7983            cx.background_spawn(request).detach_and_log_err(cx);
7984        } else if let Some(local) = self.as_local() {
7985            let servers = buffers
7986                .into_iter()
7987                .flat_map(|buffer| {
7988                    buffer.update(cx, |buffer, cx| {
7989                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
7990                    })
7991                })
7992                .collect::<HashSet<_>>();
7993            for server_id in servers {
7994                self.cancel_language_server_work(server_id, None, cx);
7995            }
7996        }
7997    }
7998
7999    pub(crate) fn cancel_language_server_work(
8000        &mut self,
8001        server_id: LanguageServerId,
8002        token_to_cancel: Option<String>,
8003        cx: &mut Context<Self>,
8004    ) {
8005        if let Some(local) = self.as_local() {
8006            let status = self.language_server_statuses.get(&server_id);
8007            let server = local.language_servers.get(&server_id);
8008            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
8009            {
8010                for (token, progress) in &status.pending_work {
8011                    if let Some(token_to_cancel) = token_to_cancel.as_ref() {
8012                        if token != token_to_cancel {
8013                            continue;
8014                        }
8015                    }
8016                    if progress.is_cancellable {
8017                        server
8018                            .notify::<lsp::notification::WorkDoneProgressCancel>(
8019                                &WorkDoneProgressCancelParams {
8020                                    token: lsp::NumberOrString::String(token.clone()),
8021                                },
8022                            )
8023                            .ok();
8024                    }
8025                }
8026            }
8027        } else if let Some((client, project_id)) = self.upstream_client() {
8028            let request = client.request(proto::CancelLanguageServerWork {
8029                project_id,
8030                work: Some(
8031                    proto::cancel_language_server_work::Work::LanguageServerWork(
8032                        proto::cancel_language_server_work::LanguageServerWork {
8033                            language_server_id: server_id.to_proto(),
8034                            token: token_to_cancel,
8035                        },
8036                    ),
8037                ),
8038            });
8039            cx.background_spawn(request).detach_and_log_err(cx);
8040        }
8041    }
8042
8043    fn register_supplementary_language_server(
8044        &mut self,
8045        id: LanguageServerId,
8046        name: LanguageServerName,
8047        server: Arc<LanguageServer>,
8048        cx: &mut Context<Self>,
8049    ) {
8050        if let Some(local) = self.as_local_mut() {
8051            local
8052                .supplementary_language_servers
8053                .insert(id, (name.clone(), server));
8054            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
8055        }
8056    }
8057
8058    fn unregister_supplementary_language_server(
8059        &mut self,
8060        id: LanguageServerId,
8061        cx: &mut Context<Self>,
8062    ) {
8063        if let Some(local) = self.as_local_mut() {
8064            local.supplementary_language_servers.remove(&id);
8065            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
8066        }
8067    }
8068
8069    pub(crate) fn supplementary_language_servers(
8070        &self,
8071    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
8072        self.as_local().into_iter().flat_map(|local| {
8073            local
8074                .supplementary_language_servers
8075                .iter()
8076                .map(|(id, (name, _))| (*id, name.clone()))
8077        })
8078    }
8079
8080    pub fn language_server_adapter_for_id(
8081        &self,
8082        id: LanguageServerId,
8083    ) -> Option<Arc<CachedLspAdapter>> {
8084        self.as_local()
8085            .and_then(|local| local.language_servers.get(&id))
8086            .and_then(|language_server_state| match language_server_state {
8087                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
8088                _ => None,
8089            })
8090    }
8091
8092    pub(super) fn update_local_worktree_language_servers(
8093        &mut self,
8094        worktree_handle: &Entity<Worktree>,
8095        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
8096        cx: &mut Context<Self>,
8097    ) {
8098        if changes.is_empty() {
8099            return;
8100        }
8101
8102        let Some(local) = self.as_local() else { return };
8103
8104        local.prettier_store.update(cx, |prettier_store, cx| {
8105            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
8106        });
8107
8108        let worktree_id = worktree_handle.read(cx).id();
8109        let mut language_server_ids = local
8110            .language_server_ids
8111            .iter()
8112            .flat_map(|((server_worktree, _), server_ids)| {
8113                server_ids
8114                    .iter()
8115                    .filter_map(|server_id| server_worktree.eq(&worktree_id).then(|| *server_id))
8116            })
8117            .collect::<Vec<_>>();
8118        language_server_ids.sort();
8119        language_server_ids.dedup();
8120
8121        let abs_path = worktree_handle.read(cx).abs_path();
8122        for server_id in &language_server_ids {
8123            if let Some(LanguageServerState::Running { server, .. }) =
8124                local.language_servers.get(server_id)
8125            {
8126                if let Some(watched_paths) = local
8127                    .language_server_watched_paths
8128                    .get(server_id)
8129                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
8130                {
8131                    let params = lsp::DidChangeWatchedFilesParams {
8132                        changes: changes
8133                            .iter()
8134                            .filter_map(|(path, _, change)| {
8135                                if !watched_paths.is_match(path) {
8136                                    return None;
8137                                }
8138                                let typ = match change {
8139                                    PathChange::Loaded => return None,
8140                                    PathChange::Added => lsp::FileChangeType::CREATED,
8141                                    PathChange::Removed => lsp::FileChangeType::DELETED,
8142                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
8143                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
8144                                };
8145                                Some(lsp::FileEvent {
8146                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
8147                                    typ,
8148                                })
8149                            })
8150                            .collect(),
8151                    };
8152                    if !params.changes.is_empty() {
8153                        server
8154                            .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
8155                            .log_err();
8156                    }
8157                }
8158            }
8159        }
8160    }
8161
8162    pub fn wait_for_remote_buffer(
8163        &mut self,
8164        id: BufferId,
8165        cx: &mut Context<Self>,
8166    ) -> Task<Result<Entity<Buffer>>> {
8167        self.buffer_store.update(cx, |buffer_store, cx| {
8168            buffer_store.wait_for_remote_buffer(id, cx)
8169        })
8170    }
8171
8172    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
8173        proto::Symbol {
8174            language_server_name: symbol.language_server_name.0.to_string(),
8175            source_worktree_id: symbol.source_worktree_id.to_proto(),
8176            language_server_id: symbol.source_language_server_id.to_proto(),
8177            worktree_id: symbol.path.worktree_id.to_proto(),
8178            path: symbol.path.path.as_ref().to_proto(),
8179            name: symbol.name.clone(),
8180            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
8181            start: Some(proto::PointUtf16 {
8182                row: symbol.range.start.0.row,
8183                column: symbol.range.start.0.column,
8184            }),
8185            end: Some(proto::PointUtf16 {
8186                row: symbol.range.end.0.row,
8187                column: symbol.range.end.0.column,
8188            }),
8189            signature: symbol.signature.to_vec(),
8190        }
8191    }
8192
8193    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
8194        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
8195        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
8196        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
8197        let path = ProjectPath {
8198            worktree_id,
8199            path: Arc::<Path>::from_proto(serialized_symbol.path),
8200        };
8201
8202        let start = serialized_symbol
8203            .start
8204            .ok_or_else(|| anyhow!("invalid start"))?;
8205        let end = serialized_symbol
8206            .end
8207            .ok_or_else(|| anyhow!("invalid end"))?;
8208        Ok(CoreSymbol {
8209            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
8210            source_worktree_id,
8211            source_language_server_id: LanguageServerId::from_proto(
8212                serialized_symbol.language_server_id,
8213            ),
8214            path,
8215            name: serialized_symbol.name,
8216            range: Unclipped(PointUtf16::new(start.row, start.column))
8217                ..Unclipped(PointUtf16::new(end.row, end.column)),
8218            kind,
8219            signature: serialized_symbol
8220                .signature
8221                .try_into()
8222                .map_err(|_| anyhow!("invalid signature"))?,
8223        })
8224    }
8225
8226    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
8227        let mut serialized_completion = proto::Completion {
8228            old_start: Some(serialize_anchor(&completion.old_range.start)),
8229            old_end: Some(serialize_anchor(&completion.old_range.end)),
8230            new_text: completion.new_text.clone(),
8231            ..proto::Completion::default()
8232        };
8233        match &completion.source {
8234            CompletionSource::Lsp {
8235                server_id,
8236                lsp_completion,
8237                lsp_defaults,
8238                resolved,
8239            } => {
8240                serialized_completion.source = proto::completion::Source::Lsp as i32;
8241                serialized_completion.server_id = server_id.0 as u64;
8242                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
8243                serialized_completion.lsp_defaults = lsp_defaults
8244                    .as_deref()
8245                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
8246                serialized_completion.resolved = *resolved;
8247            }
8248            CompletionSource::BufferWord {
8249                word_range,
8250                resolved,
8251            } => {
8252                serialized_completion.source = proto::completion::Source::BufferWord as i32;
8253                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
8254                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
8255                serialized_completion.resolved = *resolved;
8256            }
8257            CompletionSource::Custom => {
8258                serialized_completion.source = proto::completion::Source::Custom as i32;
8259                serialized_completion.resolved = true;
8260            }
8261        }
8262
8263        serialized_completion
8264    }
8265
8266    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
8267        let old_start = completion
8268            .old_start
8269            .and_then(deserialize_anchor)
8270            .context("invalid old start")?;
8271        let old_end = completion
8272            .old_end
8273            .and_then(deserialize_anchor)
8274            .context("invalid old end")?;
8275        Ok(CoreCompletion {
8276            old_range: old_start..old_end,
8277            new_text: completion.new_text,
8278            source: match proto::completion::Source::from_i32(completion.source) {
8279                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
8280                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
8281                    server_id: LanguageServerId::from_proto(completion.server_id),
8282                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
8283                    lsp_defaults: completion
8284                        .lsp_defaults
8285                        .as_deref()
8286                        .map(serde_json::from_slice)
8287                        .transpose()?,
8288                    resolved: completion.resolved,
8289                },
8290                Some(proto::completion::Source::BufferWord) => {
8291                    let word_range = completion
8292                        .buffer_word_start
8293                        .and_then(deserialize_anchor)
8294                        .context("invalid buffer word start")?
8295                        ..completion
8296                            .buffer_word_end
8297                            .and_then(deserialize_anchor)
8298                            .context("invalid buffer word end")?;
8299                    CompletionSource::BufferWord {
8300                        word_range,
8301                        resolved: completion.resolved,
8302                    }
8303                }
8304                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
8305            },
8306        })
8307    }
8308
8309    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
8310        let (kind, lsp_action) = match &action.lsp_action {
8311            LspAction::Action(code_action) => (
8312                proto::code_action::Kind::Action as i32,
8313                serde_json::to_vec(code_action).unwrap(),
8314            ),
8315            LspAction::Command(command) => (
8316                proto::code_action::Kind::Command as i32,
8317                serde_json::to_vec(command).unwrap(),
8318            ),
8319        };
8320
8321        proto::CodeAction {
8322            server_id: action.server_id.0 as u64,
8323            start: Some(serialize_anchor(&action.range.start)),
8324            end: Some(serialize_anchor(&action.range.end)),
8325            lsp_action,
8326            kind,
8327        }
8328    }
8329
8330    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
8331        let start = action
8332            .start
8333            .and_then(deserialize_anchor)
8334            .ok_or_else(|| anyhow!("invalid start"))?;
8335        let end = action
8336            .end
8337            .and_then(deserialize_anchor)
8338            .ok_or_else(|| anyhow!("invalid end"))?;
8339        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
8340            Some(proto::code_action::Kind::Action) => {
8341                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
8342            }
8343            Some(proto::code_action::Kind::Command) => {
8344                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
8345            }
8346            None => anyhow::bail!("Unknown action kind {}", action.kind),
8347        };
8348        Ok(CodeAction {
8349            server_id: LanguageServerId(action.server_id as usize),
8350            range: start..end,
8351            lsp_action,
8352        })
8353    }
8354
8355    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
8356        match &formatting_result {
8357            Ok(_) => self.last_formatting_failure = None,
8358            Err(error) => {
8359                let error_string = format!("{error:#}");
8360                log::error!("Formatting failed: {error_string}");
8361                self.last_formatting_failure
8362                    .replace(error_string.lines().join(" "));
8363            }
8364        }
8365    }
8366}
8367
8368fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
8369    let CompletionSource::BufferWord {
8370        word_range,
8371        resolved,
8372    } = &mut completion.source
8373    else {
8374        return;
8375    };
8376    if *resolved {
8377        return;
8378    }
8379
8380    if completion.new_text
8381        != snapshot
8382            .text_for_range(word_range.clone())
8383            .collect::<String>()
8384    {
8385        return;
8386    }
8387
8388    let mut offset = 0;
8389    for chunk in snapshot.chunks(word_range.clone(), true) {
8390        let end_offset = offset + chunk.text.len();
8391        if let Some(highlight_id) = chunk.syntax_highlight_id {
8392            completion
8393                .label
8394                .runs
8395                .push((offset..end_offset, highlight_id));
8396        }
8397        offset = end_offset;
8398    }
8399    *resolved = true;
8400}
8401
8402impl EventEmitter<LspStoreEvent> for LspStore {}
8403
8404fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
8405    hover
8406        .contents
8407        .retain(|hover_block| !hover_block.text.trim().is_empty());
8408    if hover.contents.is_empty() {
8409        None
8410    } else {
8411        Some(hover)
8412    }
8413}
8414
8415async fn populate_labels_for_completions(
8416    new_completions: Vec<CoreCompletion>,
8417    language: Option<Arc<Language>>,
8418    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8419    completions: &mut Vec<Completion>,
8420) {
8421    let lsp_completions = new_completions
8422        .iter()
8423        .filter_map(|new_completion| {
8424            if let Some(lsp_completion) = new_completion.source.lsp_completion(true) {
8425                Some(lsp_completion.into_owned())
8426            } else {
8427                None
8428            }
8429        })
8430        .collect::<Vec<_>>();
8431
8432    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
8433        lsp_adapter
8434            .labels_for_completions(&lsp_completions, language)
8435            .await
8436            .log_err()
8437            .unwrap_or_default()
8438    } else {
8439        Vec::new()
8440    }
8441    .into_iter()
8442    .fuse();
8443
8444    for completion in new_completions {
8445        match completion.source.lsp_completion(true) {
8446            Some(lsp_completion) => {
8447                let documentation = if let Some(docs) = lsp_completion.documentation.clone() {
8448                    Some(docs.into())
8449                } else {
8450                    None
8451                };
8452
8453                let mut label = labels.next().flatten().unwrap_or_else(|| {
8454                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
8455                });
8456                ensure_uniform_list_compatible_label(&mut label);
8457                completions.push(Completion {
8458                    label,
8459                    documentation,
8460                    old_range: completion.old_range,
8461                    new_text: completion.new_text,
8462                    source: completion.source,
8463                    confirm: None,
8464                });
8465            }
8466            None => {
8467                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
8468                ensure_uniform_list_compatible_label(&mut label);
8469                completions.push(Completion {
8470                    label,
8471                    documentation: None,
8472                    old_range: completion.old_range,
8473                    new_text: completion.new_text,
8474                    source: completion.source,
8475                    confirm: None,
8476                });
8477            }
8478        }
8479    }
8480}
8481
8482#[derive(Debug)]
8483pub enum LanguageServerToQuery {
8484    /// Query language servers in order of users preference, up until one capable of handling the request is found.
8485    FirstCapable,
8486    /// Query a specific language server.
8487    Other(LanguageServerId),
8488}
8489
8490#[derive(Default)]
8491struct RenamePathsWatchedForServer {
8492    did_rename: Vec<RenameActionPredicate>,
8493    will_rename: Vec<RenameActionPredicate>,
8494}
8495
8496impl RenamePathsWatchedForServer {
8497    fn with_did_rename_patterns(
8498        mut self,
8499        did_rename: Option<&FileOperationRegistrationOptions>,
8500    ) -> Self {
8501        if let Some(did_rename) = did_rename {
8502            self.did_rename = did_rename
8503                .filters
8504                .iter()
8505                .filter_map(|filter| filter.try_into().log_err())
8506                .collect();
8507        }
8508        self
8509    }
8510    fn with_will_rename_patterns(
8511        mut self,
8512        will_rename: Option<&FileOperationRegistrationOptions>,
8513    ) -> Self {
8514        if let Some(will_rename) = will_rename {
8515            self.will_rename = will_rename
8516                .filters
8517                .iter()
8518                .filter_map(|filter| filter.try_into().log_err())
8519                .collect();
8520        }
8521        self
8522    }
8523
8524    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
8525        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
8526    }
8527    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
8528        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
8529    }
8530}
8531
8532impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
8533    type Error = globset::Error;
8534    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
8535        Ok(Self {
8536            kind: ops.pattern.matches.clone(),
8537            glob: GlobBuilder::new(&ops.pattern.glob)
8538                .case_insensitive(
8539                    ops.pattern
8540                        .options
8541                        .as_ref()
8542                        .map_or(false, |ops| ops.ignore_case.unwrap_or(false)),
8543                )
8544                .build()?
8545                .compile_matcher(),
8546        })
8547    }
8548}
8549struct RenameActionPredicate {
8550    glob: GlobMatcher,
8551    kind: Option<FileOperationPatternKind>,
8552}
8553
8554impl RenameActionPredicate {
8555    // Returns true if language server should be notified
8556    fn eval(&self, path: &str, is_dir: bool) -> bool {
8557        self.kind.as_ref().map_or(true, |kind| {
8558            let expected_kind = if is_dir {
8559                FileOperationPatternKind::Folder
8560            } else {
8561                FileOperationPatternKind::File
8562            };
8563            kind == &expected_kind
8564        }) && self.glob.is_match(path)
8565    }
8566}
8567
8568#[derive(Default)]
8569struct LanguageServerWatchedPaths {
8570    worktree_paths: HashMap<WorktreeId, GlobSet>,
8571    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
8572}
8573
8574#[derive(Default)]
8575struct LanguageServerWatchedPathsBuilder {
8576    worktree_paths: HashMap<WorktreeId, GlobSet>,
8577    abs_paths: HashMap<Arc<Path>, GlobSet>,
8578}
8579
8580impl LanguageServerWatchedPathsBuilder {
8581    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
8582        self.worktree_paths.insert(worktree_id, glob_set);
8583    }
8584    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
8585        self.abs_paths.insert(path, glob_set);
8586    }
8587    fn build(
8588        self,
8589        fs: Arc<dyn Fs>,
8590        language_server_id: LanguageServerId,
8591        cx: &mut Context<LspStore>,
8592    ) -> LanguageServerWatchedPaths {
8593        let project = cx.weak_entity();
8594
8595        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
8596        let abs_paths = self
8597            .abs_paths
8598            .into_iter()
8599            .map(|(abs_path, globset)| {
8600                let task = cx.spawn({
8601                    let abs_path = abs_path.clone();
8602                    let fs = fs.clone();
8603
8604                    let lsp_store = project.clone();
8605                    |_, mut cx| async move {
8606                        maybe!(async move {
8607                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
8608                            while let Some(update) = push_updates.0.next().await {
8609                                let action = lsp_store
8610                                    .update(&mut cx, |this, _| {
8611                                        let Some(local) = this.as_local() else {
8612                                            return ControlFlow::Break(());
8613                                        };
8614                                        let Some(watcher) = local
8615                                            .language_server_watched_paths
8616                                            .get(&language_server_id)
8617                                        else {
8618                                            return ControlFlow::Break(());
8619                                        };
8620                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
8621                                            "Watched abs path is not registered with a watcher",
8622                                        );
8623                                        let matching_entries = update
8624                                            .into_iter()
8625                                            .filter(|event| globs.is_match(&event.path))
8626                                            .collect::<Vec<_>>();
8627                                        this.lsp_notify_abs_paths_changed(
8628                                            language_server_id,
8629                                            matching_entries,
8630                                        );
8631                                        ControlFlow::Continue(())
8632                                    })
8633                                    .ok()?;
8634
8635                                if action.is_break() {
8636                                    break;
8637                                }
8638                            }
8639                            Some(())
8640                        })
8641                        .await;
8642                    }
8643                });
8644                (abs_path, (globset, task))
8645            })
8646            .collect();
8647        LanguageServerWatchedPaths {
8648            worktree_paths: self.worktree_paths,
8649            abs_paths,
8650        }
8651    }
8652}
8653
8654struct LspBufferSnapshot {
8655    version: i32,
8656    snapshot: TextBufferSnapshot,
8657}
8658
8659/// A prompt requested by LSP server.
8660#[derive(Clone, Debug)]
8661pub struct LanguageServerPromptRequest {
8662    pub level: PromptLevel,
8663    pub message: String,
8664    pub actions: Vec<MessageActionItem>,
8665    pub lsp_name: String,
8666    pub(crate) response_channel: Sender<MessageActionItem>,
8667}
8668
8669impl LanguageServerPromptRequest {
8670    pub async fn respond(self, index: usize) -> Option<()> {
8671        if let Some(response) = self.actions.into_iter().nth(index) {
8672            self.response_channel.send(response).await.ok()
8673        } else {
8674            None
8675        }
8676    }
8677}
8678impl PartialEq for LanguageServerPromptRequest {
8679    fn eq(&self, other: &Self) -> bool {
8680        self.message == other.message && self.actions == other.actions
8681    }
8682}
8683
8684#[derive(Clone, Debug, PartialEq)]
8685pub enum LanguageServerLogType {
8686    Log(MessageType),
8687    Trace(Option<String>),
8688}
8689
8690impl LanguageServerLogType {
8691    pub fn to_proto(&self) -> proto::language_server_log::LogType {
8692        match self {
8693            Self::Log(log_type) => {
8694                let message_type = match *log_type {
8695                    MessageType::ERROR => 1,
8696                    MessageType::WARNING => 2,
8697                    MessageType::INFO => 3,
8698                    MessageType::LOG => 4,
8699                    other => {
8700                        log::warn!("Unknown lsp log message type: {:?}", other);
8701                        4
8702                    }
8703                };
8704                proto::language_server_log::LogType::LogMessageType(message_type)
8705            }
8706            Self::Trace(message) => {
8707                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
8708                    message: message.clone(),
8709                })
8710            }
8711        }
8712    }
8713
8714    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
8715        match log_type {
8716            proto::language_server_log::LogType::LogMessageType(message_type) => {
8717                Self::Log(match message_type {
8718                    1 => MessageType::ERROR,
8719                    2 => MessageType::WARNING,
8720                    3 => MessageType::INFO,
8721                    4 => MessageType::LOG,
8722                    _ => MessageType::LOG,
8723                })
8724            }
8725            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
8726        }
8727    }
8728}
8729
8730pub enum LanguageServerState {
8731    Starting {
8732        startup: Task<Option<Arc<LanguageServer>>>,
8733        /// List of language servers that will be added to the workspace once it's initialization completes.
8734        pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
8735    },
8736
8737    Running {
8738        adapter: Arc<CachedLspAdapter>,
8739        server: Arc<LanguageServer>,
8740        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
8741    },
8742}
8743
8744impl LanguageServerState {
8745    fn add_workspace_folder(&self, uri: Url) {
8746        match self {
8747            LanguageServerState::Starting {
8748                pending_workspace_folders,
8749                ..
8750            } => {
8751                pending_workspace_folders.lock().insert(uri);
8752            }
8753            LanguageServerState::Running { server, .. } => {
8754                server.add_workspace_folder(uri);
8755            }
8756        }
8757    }
8758    fn _remove_workspace_folder(&self, uri: Url) {
8759        match self {
8760            LanguageServerState::Starting {
8761                pending_workspace_folders,
8762                ..
8763            } => {
8764                pending_workspace_folders.lock().remove(&uri);
8765            }
8766            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
8767        }
8768    }
8769    fn running(
8770        workspace_folders: BTreeSet<Url>,
8771        adapter: Arc<CachedLspAdapter>,
8772        server: Arc<LanguageServer>,
8773        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
8774    ) -> Self {
8775        server.set_workspace_folders(workspace_folders);
8776        Self::Running {
8777            adapter,
8778            server,
8779            simulate_disk_based_diagnostics_completion,
8780        }
8781    }
8782}
8783
8784impl std::fmt::Debug for LanguageServerState {
8785    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8786        match self {
8787            LanguageServerState::Starting { .. } => {
8788                f.debug_struct("LanguageServerState::Starting").finish()
8789            }
8790            LanguageServerState::Running { .. } => {
8791                f.debug_struct("LanguageServerState::Running").finish()
8792            }
8793        }
8794    }
8795}
8796
8797#[derive(Clone, Debug, Serialize)]
8798pub struct LanguageServerProgress {
8799    pub is_disk_based_diagnostics_progress: bool,
8800    pub is_cancellable: bool,
8801    pub title: Option<String>,
8802    pub message: Option<String>,
8803    pub percentage: Option<usize>,
8804    #[serde(skip_serializing)]
8805    pub last_update_at: Instant,
8806}
8807
8808#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
8809pub struct DiagnosticSummary {
8810    pub error_count: usize,
8811    pub warning_count: usize,
8812}
8813
8814impl DiagnosticSummary {
8815    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
8816        let mut this = Self {
8817            error_count: 0,
8818            warning_count: 0,
8819        };
8820
8821        for entry in diagnostics {
8822            if entry.diagnostic.is_primary {
8823                match entry.diagnostic.severity {
8824                    DiagnosticSeverity::ERROR => this.error_count += 1,
8825                    DiagnosticSeverity::WARNING => this.warning_count += 1,
8826                    _ => {}
8827                }
8828            }
8829        }
8830
8831        this
8832    }
8833
8834    pub fn is_empty(&self) -> bool {
8835        self.error_count == 0 && self.warning_count == 0
8836    }
8837
8838    pub fn to_proto(
8839        &self,
8840        language_server_id: LanguageServerId,
8841        path: &Path,
8842    ) -> proto::DiagnosticSummary {
8843        proto::DiagnosticSummary {
8844            path: path.to_proto(),
8845            language_server_id: language_server_id.0 as u64,
8846            error_count: self.error_count as u32,
8847            warning_count: self.warning_count as u32,
8848        }
8849    }
8850}
8851
8852#[derive(Clone, Debug)]
8853pub enum CompletionDocumentation {
8854    /// There is no documentation for this completion.
8855    Undocumented,
8856    /// A single line of documentation.
8857    SingleLine(SharedString),
8858    /// Multiple lines of plain text documentation.
8859    MultiLinePlainText(SharedString),
8860    /// Markdown documentation.
8861    MultiLineMarkdown(SharedString),
8862}
8863
8864impl From<lsp::Documentation> for CompletionDocumentation {
8865    fn from(docs: lsp::Documentation) -> Self {
8866        match docs {
8867            lsp::Documentation::String(text) => {
8868                if text.lines().count() <= 1 {
8869                    CompletionDocumentation::SingleLine(text.into())
8870                } else {
8871                    CompletionDocumentation::MultiLinePlainText(text.into())
8872                }
8873            }
8874
8875            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
8876                lsp::MarkupKind::PlainText => {
8877                    if value.lines().count() <= 1 {
8878                        CompletionDocumentation::SingleLine(value.into())
8879                    } else {
8880                        CompletionDocumentation::MultiLinePlainText(value.into())
8881                    }
8882                }
8883
8884                lsp::MarkupKind::Markdown => {
8885                    CompletionDocumentation::MultiLineMarkdown(value.into())
8886                }
8887            },
8888        }
8889    }
8890}
8891
8892fn glob_literal_prefix(glob: &Path) -> PathBuf {
8893    glob.components()
8894        .take_while(|component| match component {
8895            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
8896            _ => true,
8897        })
8898        .collect()
8899}
8900
8901pub struct SshLspAdapter {
8902    name: LanguageServerName,
8903    binary: LanguageServerBinary,
8904    initialization_options: Option<String>,
8905    code_action_kinds: Option<Vec<CodeActionKind>>,
8906}
8907
8908impl SshLspAdapter {
8909    pub fn new(
8910        name: LanguageServerName,
8911        binary: LanguageServerBinary,
8912        initialization_options: Option<String>,
8913        code_action_kinds: Option<String>,
8914    ) -> Self {
8915        Self {
8916            name,
8917            binary,
8918            initialization_options,
8919            code_action_kinds: code_action_kinds
8920                .as_ref()
8921                .and_then(|c| serde_json::from_str(c).ok()),
8922        }
8923    }
8924}
8925
8926#[async_trait(?Send)]
8927impl LspAdapter for SshLspAdapter {
8928    fn name(&self) -> LanguageServerName {
8929        self.name.clone()
8930    }
8931
8932    async fn initialization_options(
8933        self: Arc<Self>,
8934        _: &dyn Fs,
8935        _: &Arc<dyn LspAdapterDelegate>,
8936    ) -> Result<Option<serde_json::Value>> {
8937        let Some(options) = &self.initialization_options else {
8938            return Ok(None);
8939        };
8940        let result = serde_json::from_str(options)?;
8941        Ok(result)
8942    }
8943
8944    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
8945        self.code_action_kinds.clone()
8946    }
8947
8948    async fn check_if_user_installed(
8949        &self,
8950        _: &dyn LspAdapterDelegate,
8951        _: Arc<dyn LanguageToolchainStore>,
8952        _: &AsyncApp,
8953    ) -> Option<LanguageServerBinary> {
8954        Some(self.binary.clone())
8955    }
8956
8957    async fn cached_server_binary(
8958        &self,
8959        _: PathBuf,
8960        _: &dyn LspAdapterDelegate,
8961    ) -> Option<LanguageServerBinary> {
8962        None
8963    }
8964
8965    async fn fetch_latest_server_version(
8966        &self,
8967        _: &dyn LspAdapterDelegate,
8968    ) -> Result<Box<dyn 'static + Send + Any>> {
8969        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
8970    }
8971
8972    async fn fetch_server_binary(
8973        &self,
8974        _: Box<dyn 'static + Send + Any>,
8975        _: PathBuf,
8976        _: &dyn LspAdapterDelegate,
8977    ) -> Result<LanguageServerBinary> {
8978        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
8979    }
8980}
8981
8982pub fn language_server_settings<'a>(
8983    delegate: &'a dyn LspAdapterDelegate,
8984    language: &LanguageServerName,
8985    cx: &'a App,
8986) -> Option<&'a LspSettings> {
8987    language_server_settings_for(
8988        SettingsLocation {
8989            worktree_id: delegate.worktree_id(),
8990            path: delegate.worktree_root_path(),
8991        },
8992        language,
8993        cx,
8994    )
8995}
8996
8997pub(crate) fn language_server_settings_for<'a>(
8998    location: SettingsLocation<'a>,
8999    language: &LanguageServerName,
9000    cx: &'a App,
9001) -> Option<&'a LspSettings> {
9002    ProjectSettings::get(Some(location), cx).lsp.get(language)
9003}
9004
9005pub struct LocalLspAdapterDelegate {
9006    lsp_store: WeakEntity<LspStore>,
9007    worktree: worktree::Snapshot,
9008    fs: Arc<dyn Fs>,
9009    http_client: Arc<dyn HttpClient>,
9010    language_registry: Arc<LanguageRegistry>,
9011    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
9012}
9013
9014impl LocalLspAdapterDelegate {
9015    pub fn new(
9016        language_registry: Arc<LanguageRegistry>,
9017        environment: &Entity<ProjectEnvironment>,
9018        lsp_store: WeakEntity<LspStore>,
9019        worktree: &Entity<Worktree>,
9020        http_client: Arc<dyn HttpClient>,
9021        fs: Arc<dyn Fs>,
9022        cx: &mut App,
9023    ) -> Arc<Self> {
9024        let (worktree_id, worktree_abs_path) = {
9025            let worktree = worktree.read(cx);
9026            (worktree.id(), worktree.abs_path())
9027        };
9028
9029        let load_shell_env_task = environment.update(cx, |env, cx| {
9030            env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
9031        });
9032
9033        Arc::new(Self {
9034            lsp_store,
9035            worktree: worktree.read(cx).snapshot(),
9036            fs,
9037            http_client,
9038            language_registry,
9039            load_shell_env_task,
9040        })
9041    }
9042
9043    fn from_local_lsp(
9044        local: &LocalLspStore,
9045        worktree: &Entity<Worktree>,
9046        cx: &mut App,
9047    ) -> Arc<Self> {
9048        Self::new(
9049            local.languages.clone(),
9050            &local.environment,
9051            local.weak.clone(),
9052            worktree,
9053            local.http_client.clone(),
9054            local.fs.clone(),
9055            cx,
9056        )
9057    }
9058}
9059
9060#[async_trait]
9061impl LspAdapterDelegate for LocalLspAdapterDelegate {
9062    fn show_notification(&self, message: &str, cx: &mut App) {
9063        self.lsp_store
9064            .update(cx, |_, cx| {
9065                cx.emit(LspStoreEvent::Notification(message.to_owned()))
9066            })
9067            .ok();
9068    }
9069
9070    fn http_client(&self) -> Arc<dyn HttpClient> {
9071        self.http_client.clone()
9072    }
9073
9074    fn worktree_id(&self) -> WorktreeId {
9075        self.worktree.id()
9076    }
9077
9078    fn exists(&self, path: &Path, is_dir: Option<bool>) -> bool {
9079        self.worktree.entry_for_path(path).map_or(false, |entry| {
9080            is_dir.map_or(true, |is_required_to_be_dir| {
9081                is_required_to_be_dir == entry.is_dir()
9082            })
9083        })
9084    }
9085
9086    fn worktree_root_path(&self) -> &Path {
9087        self.worktree.abs_path().as_ref()
9088    }
9089
9090    async fn shell_env(&self) -> HashMap<String, String> {
9091        let task = self.load_shell_env_task.clone();
9092        task.await.unwrap_or_default()
9093    }
9094
9095    async fn npm_package_installed_version(
9096        &self,
9097        package_name: &str,
9098    ) -> Result<Option<(PathBuf, String)>> {
9099        let local_package_directory = self.worktree_root_path();
9100        let node_modules_directory = local_package_directory.join("node_modules");
9101
9102        if let Some(version) =
9103            read_package_installed_version(node_modules_directory.clone(), package_name).await?
9104        {
9105            return Ok(Some((node_modules_directory, version)));
9106        }
9107        let Some(npm) = self.which("npm".as_ref()).await else {
9108            log::warn!(
9109                "Failed to find npm executable for {:?}",
9110                local_package_directory
9111            );
9112            return Ok(None);
9113        };
9114
9115        let env = self.shell_env().await;
9116        let output = util::command::new_smol_command(&npm)
9117            .args(["root", "-g"])
9118            .envs(env)
9119            .current_dir(local_package_directory)
9120            .output()
9121            .await?;
9122        let global_node_modules =
9123            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
9124
9125        if let Some(version) =
9126            read_package_installed_version(global_node_modules.clone(), package_name).await?
9127        {
9128            return Ok(Some((global_node_modules, version)));
9129        }
9130        return Ok(None);
9131    }
9132
9133    #[cfg(not(target_os = "windows"))]
9134    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
9135        let worktree_abs_path = self.worktree.abs_path();
9136        let shell_path = self.shell_env().await.get("PATH").cloned();
9137        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
9138    }
9139
9140    #[cfg(target_os = "windows")]
9141    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
9142        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
9143        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
9144        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
9145        which::which(command).ok()
9146    }
9147
9148    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
9149        let working_dir = self.worktree_root_path();
9150        let output = util::command::new_smol_command(&command.path)
9151            .args(command.arguments)
9152            .envs(command.env.clone().unwrap_or_default())
9153            .current_dir(working_dir)
9154            .output()
9155            .await?;
9156
9157        if output.status.success() {
9158            return Ok(());
9159        }
9160        Err(anyhow!(
9161            "{}, stdout: {:?}, stderr: {:?}",
9162            output.status,
9163            String::from_utf8_lossy(&output.stdout),
9164            String::from_utf8_lossy(&output.stderr)
9165        ))
9166    }
9167
9168    fn update_status(
9169        &self,
9170        server_name: LanguageServerName,
9171        status: language::LanguageServerBinaryStatus,
9172    ) {
9173        self.language_registry
9174            .update_lsp_status(server_name, status);
9175    }
9176
9177    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
9178        let dir = self.language_registry.language_server_download_dir(name)?;
9179
9180        if !dir.exists() {
9181            smol::fs::create_dir_all(&dir)
9182                .await
9183                .context("failed to create container directory")
9184                .log_err()?;
9185        }
9186
9187        Some(dir)
9188    }
9189
9190    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
9191        let entry = self
9192            .worktree
9193            .entry_for_path(&path)
9194            .with_context(|| format!("no worktree entry for path {path:?}"))?;
9195        let abs_path = self
9196            .worktree
9197            .absolutize(&entry.path)
9198            .with_context(|| format!("cannot absolutize path {path:?}"))?;
9199
9200        self.fs.load(&abs_path).await
9201    }
9202}
9203
9204async fn populate_labels_for_symbols(
9205    symbols: Vec<CoreSymbol>,
9206    language_registry: &Arc<LanguageRegistry>,
9207    lsp_adapter: Option<Arc<CachedLspAdapter>>,
9208    output: &mut Vec<Symbol>,
9209) {
9210    #[allow(clippy::mutable_key_type)]
9211    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
9212
9213    let mut unknown_paths = BTreeSet::new();
9214    for symbol in symbols {
9215        let language = language_registry
9216            .language_for_file_path(&symbol.path.path)
9217            .await
9218            .ok()
9219            .or_else(|| {
9220                unknown_paths.insert(symbol.path.path.clone());
9221                None
9222            });
9223        symbols_by_language
9224            .entry(language)
9225            .or_default()
9226            .push(symbol);
9227    }
9228
9229    for unknown_path in unknown_paths {
9230        log::info!(
9231            "no language found for symbol path {}",
9232            unknown_path.display()
9233        );
9234    }
9235
9236    let mut label_params = Vec::new();
9237    for (language, mut symbols) in symbols_by_language {
9238        label_params.clear();
9239        label_params.extend(
9240            symbols
9241                .iter_mut()
9242                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
9243        );
9244
9245        let mut labels = Vec::new();
9246        if let Some(language) = language {
9247            let lsp_adapter = lsp_adapter.clone().or_else(|| {
9248                language_registry
9249                    .lsp_adapters(&language.name())
9250                    .first()
9251                    .cloned()
9252            });
9253            if let Some(lsp_adapter) = lsp_adapter {
9254                labels = lsp_adapter
9255                    .labels_for_symbols(&label_params, &language)
9256                    .await
9257                    .log_err()
9258                    .unwrap_or_default();
9259            }
9260        }
9261
9262        for ((symbol, (name, _)), label) in symbols
9263            .into_iter()
9264            .zip(label_params.drain(..))
9265            .zip(labels.into_iter().chain(iter::repeat(None)))
9266        {
9267            output.push(Symbol {
9268                language_server_name: symbol.language_server_name,
9269                source_worktree_id: symbol.source_worktree_id,
9270                source_language_server_id: symbol.source_language_server_id,
9271                path: symbol.path,
9272                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
9273                name,
9274                kind: symbol.kind,
9275                range: symbol.range,
9276                signature: symbol.signature,
9277            });
9278        }
9279    }
9280}
9281
9282fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
9283    match server.capabilities().text_document_sync.as_ref()? {
9284        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
9285            lsp::TextDocumentSyncKind::NONE => None,
9286            lsp::TextDocumentSyncKind::FULL => Some(true),
9287            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
9288            _ => None,
9289        },
9290        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
9291            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
9292                if *supported {
9293                    Some(true)
9294                } else {
9295                    None
9296                }
9297            }
9298            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
9299                Some(save_options.include_text.unwrap_or(false))
9300            }
9301        },
9302    }
9303}
9304
9305/// Completion items are displayed in a `UniformList`.
9306/// Usually, those items are single-line strings, but in LSP responses,
9307/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
9308/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
9309/// 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,
9310/// breaking the completions menu presentation.
9311///
9312/// 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.
9313fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
9314    let mut new_text = String::with_capacity(label.text.len());
9315    let mut offset_map = vec![0; label.text.len() + 1];
9316    let mut last_char_was_space = false;
9317    let mut new_idx = 0;
9318    let mut chars = label.text.char_indices().fuse();
9319    let mut newlines_removed = false;
9320
9321    while let Some((idx, c)) = chars.next() {
9322        offset_map[idx] = new_idx;
9323
9324        match c {
9325            '\n' if last_char_was_space => {
9326                newlines_removed = true;
9327            }
9328            '\t' | ' ' if last_char_was_space => {}
9329            '\n' if !last_char_was_space => {
9330                new_text.push(' ');
9331                new_idx += 1;
9332                last_char_was_space = true;
9333                newlines_removed = true;
9334            }
9335            ' ' | '\t' => {
9336                new_text.push(' ');
9337                new_idx += 1;
9338                last_char_was_space = true;
9339            }
9340            _ => {
9341                new_text.push(c);
9342                new_idx += c.len_utf8();
9343                last_char_was_space = false;
9344            }
9345        }
9346    }
9347    offset_map[label.text.len()] = new_idx;
9348
9349    // Only modify the label if newlines were removed.
9350    if !newlines_removed {
9351        return;
9352    }
9353
9354    let last_index = new_idx;
9355    let mut run_ranges_errors = Vec::new();
9356    label.runs.retain_mut(|(range, _)| {
9357        match offset_map.get(range.start) {
9358            Some(&start) => range.start = start,
9359            None => {
9360                run_ranges_errors.push(range.clone());
9361                return false;
9362            }
9363        }
9364
9365        match offset_map.get(range.end) {
9366            Some(&end) => range.end = end,
9367            None => {
9368                run_ranges_errors.push(range.clone());
9369                range.end = last_index;
9370            }
9371        }
9372        true
9373    });
9374    if !run_ranges_errors.is_empty() {
9375        log::error!(
9376            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
9377            label.text
9378        );
9379    }
9380
9381    let mut wrong_filter_range = None;
9382    if label.filter_range == (0..label.text.len()) {
9383        label.filter_range = 0..new_text.len();
9384    } else {
9385        let mut original_filter_range = Some(label.filter_range.clone());
9386        match offset_map.get(label.filter_range.start) {
9387            Some(&start) => label.filter_range.start = start,
9388            None => {
9389                wrong_filter_range = original_filter_range.take();
9390                label.filter_range.start = last_index;
9391            }
9392        }
9393
9394        match offset_map.get(label.filter_range.end) {
9395            Some(&end) => label.filter_range.end = end,
9396            None => {
9397                wrong_filter_range = original_filter_range.take();
9398                label.filter_range.end = last_index;
9399            }
9400        }
9401    }
9402    if let Some(wrong_filter_range) = wrong_filter_range {
9403        log::error!(
9404            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
9405            label.text
9406        );
9407    }
9408
9409    label.text = new_text;
9410}
9411
9412#[cfg(test)]
9413mod tests {
9414    use language::HighlightId;
9415
9416    use super::*;
9417
9418    #[test]
9419    fn test_glob_literal_prefix() {
9420        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
9421        assert_eq!(
9422            glob_literal_prefix(Path::new("node_modules/**/*.js")),
9423            Path::new("node_modules")
9424        );
9425        assert_eq!(
9426            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
9427            Path::new("foo")
9428        );
9429        assert_eq!(
9430            glob_literal_prefix(Path::new("foo/bar/baz.js")),
9431            Path::new("foo/bar/baz.js")
9432        );
9433
9434        #[cfg(target_os = "windows")]
9435        {
9436            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
9437            assert_eq!(
9438                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
9439                Path::new("node_modules")
9440            );
9441            assert_eq!(
9442                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
9443                Path::new("foo")
9444            );
9445            assert_eq!(
9446                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
9447                Path::new("foo/bar/baz.js")
9448            );
9449        }
9450    }
9451
9452    #[test]
9453    fn test_multi_len_chars_normalization() {
9454        let mut label = CodeLabel {
9455            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
9456            runs: vec![(0..6, HighlightId(1))],
9457            filter_range: 0..6,
9458        };
9459        ensure_uniform_list_compatible_label(&mut label);
9460        assert_eq!(
9461            label,
9462            CodeLabel {
9463                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
9464                runs: vec![(0..6, HighlightId(1))],
9465                filter_range: 0..6,
9466            }
9467        );
9468    }
9469}