lsp_store.rs

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